Script 8 for Kitchel et al.Ā 2024 in prep taxonomic diversity manuscript.

library(data.table)
library(MuMIn)
library(ggplot2)
library(cowplot)
library(lme4)
library(stringr)

###Predicts annual dissimilarity with annual characteristics, temperature and fishing values

Pull in - region areas (if not already loaded) - region characteristics (if not already loaded); saveRDS(FishGlob_richness_year_survey, file = here::here(ā€œoutputā€,ā€œFishGlob_richness_year_survey.Rdsā€)) - fishing (if not already loaded) - temp (if not already loaded)

#physical area by year
region_area_byyear <- fread(here::here("output","region_area_byyear.csv"))

#merged fishing, temp, dissimilarities
dissimilarities_temp_fishing <- fread(here::here("output","dissimilarities_temp_fishing.csv"))

#combine
dissimilarities_temp_fishing_area <- dissimilarities_temp_fishing[region_area_byyear, on = c("survey_unit","year")]

#only jaccard for these analyses
dissimilarities_temp_fishing_area.jaccard <- dissimilarities_temp_fishing_area[dissimilarity_metric == "jaccard_dissimilarity_total",]

Add in average Julian day

#load up julian days
dates_regions <- readRDS(here::here("output","dates_regions.rds"))

#simplify
dates_regions.annual <- unique(dates_regions[,.(survey_unit, year, avg_julian_annual)])

#merge
dissimilarities_temp_fishing_area.jaccard <- dates_regions.annual[dissimilarities_temp_fishing_area.jaccard, on = c("survey_unit","year")]

Pull in palette and name helper

source(here::here("analysis_code","color_links.R"))

Pull in observed trend values

jaccard_total_coefs.r <- fread(here::here("output","jaccard_total_coefs.r.csv"))

Plot fishing and temperature vs.Ā time for all regions

#######TEMPERATURE

#set order by survey unit for plotting
all_surveys <- levels(as.factor(dissimilarities_temp_fishing_area.jaccard$survey_unit))
setorder(dissimilarities_temp_fishing_area.jaccard, survey_unit)

dissimilarities_temp_fishing_area.jaccard[,Survey_Name_Season:=factor(Survey_Name_Season, levels = unique(dissimilarities_temp_fishing_area.jaccard$Survey_Name_Season), ordered = T)]

(sbt_time_survey_facet_1_20 <- ggplot(data = dissimilarities_temp_fishing_area.jaccard[survey_unit %in% all_surveys[1:20] & year > 1979]) +
  labs(y = "Mean bottom temperature (˚C)",  x = "Year") +
  geom_point(aes(y = as.numeric(yearly_mean_bypoint_avg), x = year), alpha = 0.3) +
  geom_smooth(aes(y = as.numeric(yearly_mean_bypoint_avg), x = year), method = "lm") +
  scale_x_continuous(breaks = ~ axisTicks(., log = FALSE)) +
  theme_classic() +
  theme(axis.text.x = element_text(size = 7)) +
  facet_wrap(~Survey_Name_Season, scales= "free", ncol = 4))

ggsave(sbt_time_survey_facet_1_20, path = here::here("figures"), filename = "temp_time_survey_facet_1_20.jpg", height = 12, width =9)


(sbt_time_survey_facet_21_34 <- ggplot(data = dissimilarities_temp_fishing_area.jaccard[survey_unit %in% all_surveys[21:34] & year > 1979]) +
  labs(y = "Mean bottom temperature (˚C)",  x = "Year") +
  geom_point(aes(y = as.numeric(yearly_mean_bypoint_avg), x = year), alpha = 0.3) +
  geom_smooth(aes(y = as.numeric(yearly_mean_bypoint_avg), x = year), method = "lm") +
  scale_x_continuous(breaks = ~ axisTicks(., log = FALSE)) +
  theme_classic() +
  theme(axis.text.x = element_text(size = 7)) +
  facet_wrap(~Survey_Name_Season, scales= "free", ncol = 4))

ggsave(sbt_time_survey_facet_21_34, path = here::here("figures"), filename = "sbt_time_survey_facet_21_34.jpg", height = 12, width =9)


#######FISHING

dissimilarities_temp_fishing_area.jaccard.cc <- dissimilarities_temp_fishing_area.jaccard[complete.cases(dissimilarities_temp_fishing_area.jaccard[,summed_tonnes_scaled_byreg]),]

(fishing_time_survey_facet_1_20 <- ggplot(data = dissimilarities_temp_fishing_area.jaccard.cc[survey_unit %in% all_surveys[1:20] & year > 1979]) +
  labs(y = "Relative fishing catch",  x = "Year") +
  geom_point(aes(y = summed_tonnes_scaled_byreg, x = year), alpha = 0.3) +
  geom_smooth(aes(y = summed_tonnes_scaled_byreg, x = year), method = "lm") +
  scale_x_continuous(breaks = ~ axisTicks(., log = FALSE)) +
  theme_classic() +
  theme(axis.text.x = element_text(size = 7)) +
  facet_wrap(~Survey_Name_Season, scales= "free", ncol = 4))

ggsave(fishing_time_survey_facet_1_20, path = here::here("figures"), filename = "fishing_time_survey_facet_1_20.jpg", height = 12, width =9)


(fishing_time_survey_facet_21_34 <- ggplot(data = dissimilarities_temp_fishing_area.jaccard.cc[survey_unit %in% all_surveys[c(21:34)] & year > 1979]) +
  labs(y = "Relative fishing catch",  x = "Year") +
  geom_point(aes(y = summed_tonnes_scaled_byreg, x = year), alpha = 0.3) +
  geom_smooth(aes(y = summed_tonnes_scaled_byreg, x = year), method = "lm") +
  scale_x_continuous(breaks = ~ axisTicks(., log = FALSE)) +
  theme_classic() +
  theme(axis.text.x = element_text(size = 7)) +
  facet_wrap(~Survey_Name_Season, scales= "free", ncol = 4))

ggsave(fishing_time_survey_facet_21_34, path = here::here("figures"), filename = "fishing_time_survey_facet_21_34.jpg", height = 12, width =9)

NA
NA

Plot fishing and temperature vs.Ā dissimilarity for all regions

#####MEAN TEMP
(preds_sbt_mean_temp_survey_facet_1_20 <- ggplot(data = dissimilarities_temp_fishing_area.jaccard[survey_unit %in% all_surveys[1:20] & year > 1979]) +
  labs(x = "Mean bottom temperature (˚C)",  y = "β-diversity") +
  geom_point(aes(x = as.numeric(yearly_mean_bypoint_avg), y = annual_dissimilarity_value), alpha = 0.3) +
  geom_smooth(aes(x = as.numeric(yearly_mean_bypoint_avg), y = annual_dissimilarity_value), method = "lm") +
  facet_wrap(~Survey_Name_Season, scales= "free", ncol = 4) +
  theme_classic())

ggsave(preds_sbt_mean_temp_survey_facet_1_20, path = here::here("figures"), filename = "preds_sbt_mean_temp_survey_facet_1_20.jpg", height = 12, width =9)


(preds_sbt_mean_temp_survey_facet_21_34 <- ggplot(data = dissimilarities_temp_fishing_area.jaccard[survey_unit %in% all_surveys[21:34] & year > 1979]) +
  labs(x = "Mean bottom temperature (˚C)",  y = "β-diversity") +
  geom_point(aes(x = as.numeric(yearly_mean_bypoint_avg), y = annual_dissimilarity_value), alpha = 0.3) +
  geom_smooth(aes(x = as.numeric(yearly_mean_bypoint_avg), y = annual_dissimilarity_value), method = "lm") +
  facet_wrap(~Survey_Name_Season, scales= "free", ncol = 4) +
  theme_classic())

ggsave(preds_sbt_mean_temp_survey_facet_21_34, path = here::here("figures"), filename = "preds_sbt_mean_temp_survey_facet_21_34.jpg", height = 12, width =9)


#####MINIMUM TEMP
(preds_sbt_min_temp_survey_facet_1_20 <- ggplot(data = dissimilarities_temp_fishing_area.jaccard[survey_unit %in% all_surveys[1:20] & year > 1979]) +
  labs(x = "Minimum bottom temperature (˚C)",  y = "β-diversity") +
  geom_point(aes(x = as.numeric(yearly_min_bypoint_avg), y = annual_dissimilarity_value), alpha = 0.3) +
  geom_smooth(aes(x = as.numeric(yearly_min_bypoint_avg), y = annual_dissimilarity_value), method = "lm") +
  facet_wrap(~Survey_Name_Season, scales= "free", ncol = 4) +
  theme_classic())

ggsave(preds_sbt_min_temp_survey_facet_1_20, path = here::here("figures"), filename = "preds_sbt_min_temp_survey_facet_1_20.jpg", height = 12, width =9)


(preds_sbt_min_temp_survey_facet_21_34 <- ggplot(data = dissimilarities_temp_fishing_area.jaccard[survey_unit %in% all_surveys[21:34] & year > 1979]) +
  labs(x = "Minimum bottom temperature (˚C)",  y = "β-diversity") +
  geom_point(aes(x = as.numeric(yearly_min_bypoint_avg), y = annual_dissimilarity_value), alpha = 0.3) +
  geom_smooth(aes(x = as.numeric(yearly_min_bypoint_avg), y = annual_dissimilarity_value), method = "lm") +
  facet_wrap(~Survey_Name_Season, scales= "free", ncol = 4) +
  theme_classic())

ggsave(preds_sbt_min_temp_survey_facet_21_34, path = here::here("figures"), filename = "preds_sbt_min_temp_survey_facet_21_34.jpg", height = 12, width =9)


#######FISHING

dissimilarities_temp_fishing_area.jaccard.cc <- dissimilarities_temp_fishing_area.jaccard[complete.cases(dissimilarities_temp_fishing_area.jaccard[,summed_tonnes_scaled_byreg]),]

(preds_sbt_mean_fishing_survey_facet_1_20 <- ggplot(data = dissimilarities_temp_fishing_area.jaccard.cc[survey_unit %in% all_surveys[1:20] & year > 1979]) +
  labs(x = "Relative fishing catch",  y = "β-diversity") +
  geom_point(aes(x = summed_tonnes_scaled_byreg, y = annual_dissimilarity_value), alpha = 0.3) +
  geom_smooth(aes(x = summed_tonnes_scaled_byreg, y = annual_dissimilarity_value), method = "lm") +
  facet_wrap(~Survey_Name_Season, scales= "free", ncol = 4) +
  theme_classic())

ggsave(preds_sbt_mean_fishing_survey_facet_1_20, path = here::here("figures"), filename = "preds_sbt_mean_fishing_survey_facet_1_20.jpg", height = 12, width =9)


(preds_sbt_mean_fishing_survey_facet_21_34 <- ggplot(data = dissimilarities_temp_fishing_area.jaccard.cc[survey_unit %in% all_surveys[c(21:34)] & year > 1979]) +
  labs(x = "Relative fishing catch",  y = "β-diversity") +
  geom_point(aes(x = summed_tonnes_scaled_byreg, y = annual_dissimilarity_value), alpha = 0.3) +
  geom_smooth(aes(x = summed_tonnes_scaled_byreg, y = annual_dissimilarity_value), method = "lm") +
  facet_wrap(~Survey_Name_Season, scales= "free", ncol = 4) +
  theme_classic())

ggsave(preds_sbt_mean_fishing_survey_facet_21_34, path = here::here("figures"), filename = "preds_sbt_mean_fishing_survey_facet_21_34.jpg", height = 12, width =9)

NA
NA

###Plot number of tows per year per region

tows_year <- unique(dissimilarities_temp_fishing_area.jaccard[,.(survey_unit, haul_id_count_annual, area_km, year, Survey_Name_Season)])

min_haul_density <- min(tows_year$haul_id_count_annual/tows_year$area_km)
max_haul_density <- max(tows_year$haul_id_count_annual/tows_year$area_km)

(tow_density_survey_facet_1_20 <- ggplot(data = tows_year[survey_unit %in% all_surveys[1:20]]) +
  labs(x = "Year",  y = expression("Tow density (tows per km"^2*")")) +
  geom_point(aes(x = year, y = haul_id_count_annual/area_km)) +
  ylim(c(min_haul_density-0.0001, max_haul_density+0.0001)) +
  facet_wrap(~Survey_Name_Season, ncol = 4) +
  theme_classic())

ggsave(tow_density_survey_facet_1_20, path = here::here("figures"), filename = "tow_density_survey_facet_1_20.jpg", height = 12, width =9)


(tow_density_survey_facet_21_34 <- ggplot(data = tows_year[survey_unit %in% all_surveys[21:34]]) +
  labs(x = "Year",  y = expression("Tow density (tows per km"^2*")")) +
  geom_point(aes(x = year, y = haul_id_count_annual/area_km)) +
  ylim(c(min_haul_density-0.0001, max_haul_density+0.0001)) +
  facet_wrap(~Survey_Name_Season, ncol = 4) +
  theme_classic())

ggsave(tow_density_survey_facet_21_34, path = here::here("figures"), filename = "tow_density_survey_facet_21_34.jpg", height = 12, width =9)

#minimum and maximum dissimilarity value
min_dissimilarity <- min(dissimilarities_temp_fishing_area.jaccard$annual_dissimilarity_value)
max_dissimilarity <- max(dissimilarities_temp_fishing_area.jaccard$annual_dissimilarity_value)

#how does tow density vary with dissimilarity?
tow_density_dissimilarity_1_20 <- 
  ggplot(data = dissimilarities_temp_fishing_area.jaccard[dissimilarity_metric == "jaccard_dissimilarity_total" & survey_unit %in% all_surveys[1:20]]) +
  geom_point(aes(x = (haul_id_count_annual/area_km), y = annual_dissimilarity_value, color = year), size = 2) +
  viridis::scale_color_viridis() +
  facet_wrap(~Survey_Name_Season, ncol = 4) +
  labs(x = "Tow density (tows per km^2)", y = "β-diversity", color = "Year") +
    xlim(c(min_haul_density-0.0001, max_haul_density+0.0001)) +
    ylim(c(min_dissimilarity-0.01,max_dissimilarity+0.01)) +
  theme_classic()

ggsave(tow_density_dissimilarity_1_20, path = here::here("figures"), filename = "tow_density_dissimilarity_1_20.jpg", height = 12, width =9)

tow_density_dissimilarity_21_34 <- 
  ggplot(data = dissimilarities_temp_fishing_area.jaccard[dissimilarity_metric == "jaccard_dissimilarity_total" & survey_unit %in% all_surveys[21:34]]) +
  geom_point(aes(x = (haul_id_count_annual/area_km), y = annual_dissimilarity_value, color = year), size = 2) +
  viridis::scale_color_viridis() +
  facet_wrap(~Survey_Name_Season, ncol = 4) +
  labs(x = "Tow density (tows per km^2)", y = "β-diversity", color = "Year") +
    xlim(c(min_haul_density-0.0001, max_haul_density+0.0001)) +
    ylim(c(min_dissimilarity-0.01,max_dissimilarity+0.01)) +
  theme_classic()

ggsave(tow_density_dissimilarity_21_34, path = here::here("figures"), filename = "tow_density_dissimilarity_21_34.jpg", height = 12, width =9)

###Set up dredge to identify best performing models


options(na.action = "na.fail")

dissimilarity_covariates_dredge.dt <- dissimilarities_temp_fishing_area.jaccard[,.
                  (year, survey_unit,
                    yearly_mean_bypoint_avg, yearly_max_bypoint_avg, yearly_min_bypoint_avg,yearly_seas_bypoint_avg,
                    yearly_mean_bypoint_SD, yearly_max_bypoint_SD, yearly_min_bypoint_SD,yearly_seas_bypoint_SD,
                    yearly_mean_bypoint_avg.s, yearly_max_bypoint_avg.s, yearly_min_bypoint_avg.s,yearly_seas_bypoint_avg.s,
                    annual_dissimilarity_value,
                    haul_id_count_annual,
                    spp_count_annual, depth_annual_avg,
                    depth_annual_range, latitude_annual_avg,
                    latitude_annual_range, area_km, avg_julian_annual, summed_tonnes_scaled_byreg)]

#merge in with colors for plotting predictions by survey
dissimilarity_covariates_dredge.dt <- color_link[dissimilarity_covariates_dredge.dt, on = "survey_unit"]

#If NA for any covariate, delete row
View(dissimilarity_covariates_dredge.dt)
#Deleted:
  #Before 1980 and after 2019
  #Gulf of Saint Laurence South (no depth data)
  #No clear SAU match for Rockall Plateau
dissimilarity_covariates_dredge.dt <- dissimilarity_covariates_dredge.dt[complete.cases(dissimilarity_covariates_dredge.dt)]


dissimilarity_covariates_dredge.dt[, yearly_mean_bypoint_avg.scaledacrossall := scale(yearly_mean_bypoint_avg)][, yearly_mean_bypoint_SD.scaledacrossall := scale(yearly_mean_bypoint_SD)][, yearly_min_bypoint_avg.scaledacrossall := scale(yearly_min_bypoint_avg)][, yearly_max_bypoint_avg.scaledacrossall := scale(yearly_max_bypoint_avg)][, yearly_seas_bypoint_avg.scaledacrossall := scale(yearly_seas_bypoint_avg)][,haul_id_count_annual.scaledacrossall := scale(haul_id_count_annual)][,spp_count_annual.scaledacrossall := scale(spp_count_annual)][,depth_annual_avg.scaledacrossall := scale(depth_annual_avg)][,depth_annual_range.scaledacrossall := scale(depth_annual_range)] [,latitude_annual_avg.scaledacrossall := scale(latitude_annual_avg)][,latitude_annual_range.scaledacrossall := scale(latitude_annual_range)][,area_km.scaledacrossall := scale(area_km)][,julian_scaled := scale(avg_julian_annual)]
###Full model
temp + survey_unit + fishing + area + latitude range + latitude average + depth range + depth average + spp count + # of hauls + julian day + AR for year

For temperature, we will look at: -mean (scaled across all regions) -max (scaled across all regions) -min (scaled across all regions) -seas (scaled across all regions) -SD

Comparing temp variables AND the presence/absence of a temporal autocorrelation term


global_mod_mean_temp_gls <- gls(annual_dissimilarity_value ~ 
                             survey_unit*yearly_mean_bypoint_avg.scaledacrossall + #temp and survey unit (possible interaction)
                             survey_unit*summed_tonnes_scaled_byreg + #fishing effort and survey unit (possible interaction)
                             area_km.scaledacrossall + #area
                             latitude_annual_range.scaledacrossall + #latitude range
                             latitude_annual_avg.scaledacrossall + #latitude avg
                             depth_annual_range.scaledacrossall + #depth range
                             depth_annual_avg.scaledacrossall + #depth avg
                             spp_count_annual.scaledacrossall + #spp #
                             haul_id_count_annual.scaledacrossall +
                             julian_scaled,
                           correlation = corAR1(form=~year | survey_unit),
                             data = dissimilarity_covariates_dredge.dt)

global_mod_mean_temp_lm <- lm(annual_dissimilarity_value ~ 
                             survey_unit*yearly_mean_bypoint_avg.scaledacrossall + #temp and survey unit (possible interaction)
                             survey_unit*summed_tonnes_scaled_byreg + #fishing effort and survey unit (possible interaction)
                             area_km.scaledacrossall + #area
                             latitude_annual_range.scaledacrossall + #latitude range
                             latitude_annual_avg.scaledacrossall + #latitude avg
                             depth_annual_range.scaledacrossall + #depth range
                             depth_annual_avg.scaledacrossall + #depth avg
                             spp_count_annual.scaledacrossall + #spp #
                             haul_id_count_annual.scaledacrossall +
                             julian_scaled,
                             data = dissimilarity_covariates_dredge.dt)

global_mod_max_temp_lm <- lm(annual_dissimilarity_value ~ 
                             survey_unit*yearly_max_bypoint_avg.scaledacrossall + #temp and survey unit (possible interaction)
                             survey_unit*summed_tonnes_scaled_byreg + #fishing effort and survey unit (possible interaction)
                             area_km.scaledacrossall + #area
                             latitude_annual_range.scaledacrossall + #latitude range
                             latitude_annual_avg.scaledacrossall + #latitude avg
                             depth_annual_range.scaledacrossall + #depth range
                             depth_annual_avg.scaledacrossall + #depth avg
                             spp_count_annual.scaledacrossall + #spp #
                             haul_id_count_annual.scaledacrossall +
                            julian_scaled,
                             data = dissimilarity_covariates_dredge.dt)

global_mod_max_temp_gls <-gls(annual_dissimilarity_value ~ 
                             survey_unit*yearly_max_bypoint_avg.scaledacrossall + #temp and survey unit (possible interaction)
                             survey_unit*summed_tonnes_scaled_byreg + #fishing effort and survey unit (possible interaction)
                             area_km.scaledacrossall + #area
                             latitude_annual_range.scaledacrossall + #latitude range
                             latitude_annual_avg.scaledacrossall + #latitude avg
                             depth_annual_range.scaledacrossall + #depth range
                             depth_annual_avg.scaledacrossall + #depth avg
                             spp_count_annual.scaledacrossall + #spp #
                             haul_id_count_annual.scaledacrossall +
                            julian_scaled,
                            correlation = corAR1(form=~year | survey_unit),
                             data = dissimilarity_covariates_dredge.dt)

global_mod_min_temp_lm <- lm(annual_dissimilarity_value ~ 
                             survey_unit*yearly_min_bypoint_avg.scaledacrossall + #temp and survey unit (possible interaction)
                             survey_unit*summed_tonnes_scaled_byreg + #fishing effort and survey unit (possible interaction)
                             area_km.scaledacrossall + #area
                             latitude_annual_range.scaledacrossall + #latitude range
                             latitude_annual_avg.scaledacrossall + #latitude avg
                             depth_annual_range.scaledacrossall + #depth range
                             depth_annual_avg.scaledacrossall + #depth avg
                             spp_count_annual.scaledacrossall + #spp #
                             haul_id_count_annual.scaledacrossall +
                            julian_scaled,
                             data = dissimilarity_covariates_dredge.dt)

global_mod_min_temp_gls <-gls(annual_dissimilarity_value ~ 
                             survey_unit*yearly_min_bypoint_avg.scaledacrossall + #temp and survey unit (possible interaction)
                             survey_unit*summed_tonnes_scaled_byreg + #fishing effort and survey unit (possible interaction)
                             area_km.scaledacrossall + #area
                             latitude_annual_range.scaledacrossall + #latitude range
                             latitude_annual_avg.scaledacrossall + #latitude avg
                             depth_annual_range.scaledacrossall + #depth range
                             depth_annual_avg.scaledacrossall + #depth avg
                             spp_count_annual.scaledacrossall + #spp #
                             haul_id_count_annual.scaledacrossall +
                            julian_scaled,
                            correlation = corAR1(form=~year | survey_unit),
                             data = dissimilarity_covariates_dredge.dt)

global_mod_seas_temp_lm <- lm(annual_dissimilarity_value ~ 
                             survey_unit*yearly_seas_bypoint_avg.scaledacrossall + #temp and survey unit (possible interaction)
                             survey_unit*summed_tonnes_scaled_byreg + #fishing effort and survey unit (possible interaction)
                             area_km.scaledacrossall + #area
                             latitude_annual_range.scaledacrossall + #latitude range
                             latitude_annual_avg.scaledacrossall + #latitude avg
                             depth_annual_range.scaledacrossall + #depth range
                             depth_annual_avg.scaledacrossall + #depth avg
                             spp_count_annual.scaledacrossall + #spp #
                             haul_id_count_annual.scaledacrossall +
                             julian_scaled,
                             data = dissimilarity_covariates_dredge.dt)

global_mod_seas_temp_gls <- gls(annual_dissimilarity_value ~ 
                             survey_unit*yearly_seas_bypoint_avg.scaledacrossall + #temp and survey unit (possible interaction)
                             survey_unit*summed_tonnes_scaled_byreg + #fishing effort and survey unit (possible interaction)
                             area_km.scaledacrossall + #area
                             latitude_annual_range.scaledacrossall + #latitude range
                             latitude_annual_avg.scaledacrossall + #latitude avg
                             depth_annual_range.scaledacrossall + #depth range
                             depth_annual_avg.scaledacrossall + #depth avg
                             spp_count_annual.scaledacrossall + #spp #
                             haul_id_count_annual.scaledacrossall +
                             julian_scaled,
                             correlation = corAR1(form=~year | survey_unit),
                             data = dissimilarity_covariates_dredge.dt)

global_mod_SD_temp_lm <- lm(annual_dissimilarity_value ~ 
                             survey_unit*yearly_mean_bypoint_SD.scaledacrossall + #temp and survey unit (possible interaction)
                             survey_unit*summed_tonnes_scaled_byreg + #fishing effort and survey unit (possible interaction)
                             area_km.scaledacrossall + #area
                             latitude_annual_range.scaledacrossall + #latitude range
                             latitude_annual_avg.scaledacrossall + #latitude avg
                             depth_annual_range.scaledacrossall + #depth range
                             depth_annual_avg.scaledacrossall + #depth avg
                             spp_count_annual.scaledacrossall + #spp #
                             haul_id_count_annual.scaledacrossall +
                           julian_scaled,
                             data = dissimilarity_covariates_dredge.dt)

global_mod_SD_temp_gls <- gls(annual_dissimilarity_value ~ 
                             survey_unit*yearly_mean_bypoint_SD.scaledacrossall + #temp and survey unit (possible interaction)
                             survey_unit*summed_tonnes_scaled_byreg + #fishing effort and survey unit (possible interaction)
                             area_km.scaledacrossall + #area
                             latitude_annual_range.scaledacrossall + #latitude range
                             latitude_annual_avg.scaledacrossall + #latitude avg
                             depth_annual_range.scaledacrossall + #depth range
                             depth_annual_avg.scaledacrossall + #depth avg
                             spp_count_annual.scaledacrossall + #spp #
                             haul_id_count_annual.scaledacrossall +
                           julian_scaled,
                              correlation = corAR1(form=~year | survey_unit),
                             data = dissimilarity_covariates_dredge.dt)

View(AICc(global_mod_mean_temp_lm, global_mod_max_temp_lm, global_mod_min_temp_lm, global_mod_seas_temp_lm, global_mod_SD_temp_lm,
          global_mod_mean_temp_gls, global_mod_max_temp_gls, global_mod_min_temp_gls, global_mod_seas_temp_gls, global_mod_SD_temp_gls))

#build data table to report AICc
global_mod_temp_table <- data.table(
  `Temporal autocorrelation` = c(
    c(rep(F,5),rep(T,5))
  ),
  `Temperature variable` = rep(c(                  
              "Average mean SBT",
              "Average maximum SBT",                        
              "Average minimum SBT",                  
              "Average SBT seasonality",                 
              "SBT SD"),2),
  deltaAICc = signif(min(AICc(global_mod_mean_temp_lm, global_mod_max_temp_lm, global_mod_min_temp_lm, global_mod_seas_temp_lm, global_mod_SD_temp_lm,
          global_mod_mean_temp_gls, global_mod_max_temp_gls, global_mod_min_temp_gls, global_mod_seas_temp_gls, global_mod_SD_temp_gls)[,2])-AICc(global_mod_mean_temp_lm, global_mod_max_temp_lm, global_mod_min_temp_lm, global_mod_seas_temp_lm, global_mod_SD_temp_lm,
          global_mod_mean_temp_gls, global_mod_max_temp_gls, global_mod_min_temp_gls, global_mod_seas_temp_gls, global_mod_SD_temp_gls)[,2],2))

#order by aicc
setorder(global_mod_temp_table,cols = -"deltaAICc")

global_mod_temp_table[,Rank := seq(1,10,by = 1)]

global_mod_sbt_table <- global_mod_temp_table[,.(Rank,`Temporal autocorrelation`,`Temperature variable`, deltaAICc)]

fwrite(global_mod_sbt_table, here::here("output","global_mod_sbt_table.csv"))

Best performing global model includes minimum temperature (centered and scaled) (Still the case as of May 6, 2024)

Now, look at different combinations of all predictors (min temp) using dredge

Global model: global_mod_min_temp

options(na.action = "na.fail") #  prevent fitting sub-models to different datasets
dd <- dredge(global_mod_min_temp)
Fixed term is "(Intercept)"
dd.dt <- data.table(dd)
View(dd)

#only models less than 4 delta AICc (2 models)
dd.dt.2 <- dd.dt[delta <= 2,]

colnames(dd.dt.2)
 [1] "(Intercept)"                                        "area_km.scaledacrossall"                           
 [3] "depth_annual_avg.scaledacrossall"                   "depth_annual_range.scaledacrossall"                
 [5] "haul_id_count_annual.scaledacrossall"               "julian_scaled"                                     
 [7] "latitude_annual_avg.scaledacrossall"                "latitude_annual_range.scaledacrossall"             
 [9] "spp_count_annual.scaledacrossall"                   "summed_tonnes_scaled_byreg"                        
[11] "survey_unit"                                        "yearly_min_bypoint_avg.scaledacrossall"            
[13] "summed_tonnes_scaled_byreg:survey_unit"             "survey_unit:yearly_min_bypoint_avg.scaledacrossall"
[15] "df"                                                 "logLik"                                            
[17] "AICc"                                               "delta"                                             
[19] "weight"                                            
#in this step, we delete coefficient values because we will pull them back in later when we calculate both SE and coefficients (other than interaction, which we keep here)
dd.dt.2.formatted <- dd.dt.2[,Rank := as.numeric(rownames(dd.dt.2))][,.(Rank,
                                `summed_tonnes_scaled_byreg:survey_unit`,
                                `survey_unit:yearly_min_bypoint_avg.scaledacrossall`,
                                delta,
                                weight, survey_unit
                                )]

#add r-squared values
# Iterate through the best models and extract R-squared values
r_squared_values <-list()
for (i in 1:nrow(dd.dt.2.formatted)) {
  summary_data <- summary(get.models(dd, subset = i)[[1]])
  r_squared <- signif(summary_data$r.squared,2)
  r_squared_values <- unlist(c(r_squared_values,r_squared))
}

dd.dt.2.formatted[,"R squared" := r_squared_values]

#empty data table

model_coef_se_fill <- data.table(Rank = as.numeric(), coef_name = as.character(),coef = as.numeric(), se = as.numeric())

for (i in 1:nrow(dd.dt.2.formatted)){
  model_coef_se_single <- data.table(unlist(coefTable(dd,full = T)[[i]]))
  model_coef_se_single[,coef_names := rownames(unlist(coefTable(dd,full = T)[[i]]))]
  model_coef_se_single[,Rank := i]
  
  colnames(model_coef_se_single) <- c("coef","se","df","coef_name","Rank")
  
  #reduce to columns we need
  model_coef_se_single <- model_coef_se_single[,.(Rank, coef_name, coef, se)]
  
  model_coef_se_fill <- rbind(model_coef_se_fill,model_coef_se_single)
}

#format to merge with model rankings and averaged model
model_coef_se_fill[,coef_se := paste0(round(coef,3)," ± ",round(se,3))]

#delete extra columns
model_coef_se_fill <- model_coef_se_fill[,.(Rank,coef_name,coef_se)]

#long to wide
model_coef_se_fill.w <- dcast(model_coef_se_fill, formula = Rank ~ coef_name, value.var = c("coef_se"))

#merge model_coef_se_fill with dd.dt.2.formatted
model_coef_se_AIC <- dd.dt.2.formatted[model_coef_se_fill.w, on = "Rank"]

#model average all models with delta < 4 (50 models)
model_avg_delta4 <-model.avg(dd, subset = delta < 4, fit = T) #NB: The ā€˜subset’ (or ā€˜conditional’) average only   averages over the models where the parameter appears. An alternative, the ā€˜full’ average assumes that a variable is included in every model, but in some models the corresponding coefficient (and its respective variance) is set to zero. Unlike the ā€˜subset average’, it does not have a tendency of biasing the value away from zero. The ā€˜full’ average is a type of shrinkage estimator, and for variables with a weak relationship to the response it is smaller than ā€˜subset’ estimators., fit = T fits the component models again

model_avg_values <- as.data.table(coefTable(model_avg_delta4,fill = T)) # with SE
coef_names <- names(coef(model.avg(dd, subset = delta < 4)))
model_avg_values[,coef_name:=coef_names][,coef:=Estimate][,Estimate:=NULL][,df:=NULL][,se:= `Std. Error`][,`Std. Error` := NULL]

#new column with coef and SE
model_avg_values[,coef_se := paste0(round(coef,3)," ± ",round(se,3))]

#long to wide for model avg
model_avg.wide <- dcast(model_avg_values, formula = . ~ coef_name, value.var = c("coef_se"))

#add rank of "model avg" to table
model_avg.wide[,Rank := "Model avg"]

best_model_sbt_jaccard_table_formatted <- rbind(model_coef_se_AIC, model_avg.wide, fill = T)

#get rid of interaction coefficients
best_model_sbt_jaccard_table_formatted.r <- best_model_sbt_jaccard_table_formatted[,.(Rank,`(Intercept)`,area_km.scaledacrossall,
                                depth_annual_avg.scaledacrossall,
                                depth_annual_range.scaledacrossall,
                                haul_id_count_annual.scaledacrossall,
                                julian_scaled,
                                latitude_annual_avg.scaledacrossall,
                                latitude_annual_range.scaledacrossall,
                                spp_count_annual.scaledacrossall,
                                summed_tonnes_scaled_byreg,
                                survey_unit,
                                yearly_min_bypoint_avg.scaledacrossall,
                                `summed_tonnes_scaled_byreg:survey_unit`,
                                `survey_unit:yearly_min_bypoint_avg.scaledacrossall`,
                                `R squared`,
                                delta,
                                weight
                                )]

#round to 2 significant figures

#names of numeric columns
numeric_cols <- names(best_model_sbt_jaccard_table_formatted.r)[sapply(best_model_sbt_jaccard_table_formatted.r, is.numeric)]

# Apply signif() only to numeric columns
best_model_sbt_jaccard_table_formatted.r[, (numeric_cols) := lapply(.SD, function(x) if (is.numeric(x)) signif(x, digits = 2) else x), .SDcols = numeric_cols]

#change column names, in caption note that all variables are centered and scaled
colnames(best_model_sbt_jaccard_table_formatted.r) <- c(
"Rank",                                              
"Intercept",                                     
"Area",       #scaled across all                    
"Average depth",                  
"Depth range",                
"Number of tows",     
"Average Julian day",
"Average latitude",               
"Latitude range",             
"Species count",                  
"Relative catch", #scaled within region                       
"Survey",                                       
"Average minimum temperature",            
"Survey * relative catch",            
"Survey * avg min temperature",
"R squared",
paste0("\u0394"," AICc"),                                             
paste0("\u03C9"))



#save as csv

fwrite(best_model_sbt_jaccard_table_formatted.r,here::here("output","best_model_sbt_jaccard_table_formatted.csv"))

Take aways Dissimilarity increases with increasing avg # tows Dissimilarity decreases with increasing avg latitude Dissimilarity decreases with increasing Julian day of sampling Dissimilarity increases with increasing latitude range Dissimilarity increases with increasing fishing effort Dissimilarity decreases with increasing depth range Dissimilarity increases with increasing average depth Dissimilarity increases with increasing area Dissimilarity decreases with increasing minimum temperature Dissimilarity increases with increasing # spp Dissimilarity increases with relative fishing catch

Predict dissimilarity across years using averaged model (model_avg_delta4)

dissimilarity_covariates_dredge.dt_predictions <- copy(dissimilarity_covariates_dredge.dt)

  #allowing temp and fishing to vary (aka no changes)
  dissimilarity_covariates_dredge.dt_predictions[,pred_dissim := predict(model_avg_delta4, se.fit = T, full = F)[[1]]][,pred_se := predict(model_avg_delta4, se.fit = T, full = F)[[2]]] #full allows us to switch back to mixed effect models
Warning: argument 'full' ignoredWarning: argument 'full' ignored
  
  
  
  #constant temp in regions (aka take mean of temperature values within survey units so they are the same value within each year for a survey)
  dissimilarity_covariates_dredge.dt_predictions_consistenttempinreg <- copy(dissimilarity_covariates_dredge.dt)
  dissimilarity_covariates_dredge.dt_predictions_consistenttempinreg[,yearly_min_bypoint_avg.scaledacrossall:=mean(yearly_min_bypoint_avg.scaledacrossall),.(survey_unit)]

  #constant fishing in regions (aka take mean of fishing values within survey units so they are the same value within each year for a survey)
  dissimilarity_covariates_dredge.dt_predictions_consistentfishinginreg <- copy(dissimilarity_covariates_dredge.dt)
  dissimilarity_covariates_dredge.dt_predictions_consistentfishinginreg[,summed_tonnes_scaled_byreg:=mean(summed_tonnes_scaled_byreg),.(survey_unit)]

#and then with consistent temp and fishing in regions (aka take mean of both min temp and fishing)
dissimilarity_covariates_dredge.dt_predictions_consistenttempfishinginreg <- copy(dissimilarity_covariates_dredge.dt)
dissimilarity_covariates_dredge.dt_predictions_consistenttempfishinginreg[,summed_tonnes_scaled_byreg:=mean(summed_tonnes_scaled_byreg),.(survey_unit)][,yearly_min_bypoint_avg.scaledacrossall:=mean(yearly_min_bypoint_avg.scaledacrossall),.(survey_unit)]


#allowing temp and fishing to vary within regs (normal)
    dissimilarity_covariates_dredge.dt_predictions[,pred_dissim := 
                                                     predict(model_avg_delta4, se.fit = T, full = F, newdata =   dissimilarity_covariates_dredge.dt_predictions)[[1]]][,pred_se := 
                                                                                                                                                                         predict(model_avg_delta4, se.fit = T, full = F, newdata =   dissimilarity_covariates_dredge.dt_predictions)[[2]]]
Warning: argument 'full' ignoredWarning: argument 'full' ignored
  
#allowing only fishing to vary within regions (with mean temp)
  
   dissimilarity_covariates_dredge.dt_predictions_consistenttempinreg[,pred_dissim := 
                                                                        predict(model_avg_delta4, se.fit = T, full = F, newdata = dissimilarity_covariates_dredge.dt_predictions_consistenttempinreg)[[1]]][,pred_se :=
                                                                                                                                                                                                              predict(model_avg_delta4, se.fit = T, full = F, newdata = dissimilarity_covariates_dredge.dt_predictions_consistenttempinreg)[[2]]]
Warning: argument 'full' ignoredWarning: argument 'full' ignored
  
  
#allowing only temperature to vary within regions (with mean fishing pressure)
     
   dissimilarity_covariates_dredge.dt_predictions_consistentfishinginreg[,pred_dissim :=
                                                                           predict(model_avg_delta4, se.fit = T, full = F, newdata = dissimilarity_covariates_dredge.dt_predictions_consistentfishinginreg)[[1]]][,pred_se := 
                                                                                                                                                                                                                                  predict(model_avg_delta4, se.fit = T, full = F, newdata = dissimilarity_covariates_dredge.dt_predictions_consistentfishinginreg)[[2]]]
Warning: argument 'full' ignoredWarning: argument 'full' ignored
   
#and then with consistent temp and fishing across regions (mean of both fishing and temp)
dissimilarity_covariates_dredge.dt_predictions_consistenttempfishinginreg <- copy(dissimilarity_covariates_dredge.dt)
dissimilarity_covariates_dredge.dt_predictions_consistenttempfishinginreg[,summed_tonnes_scaled_byreg:=mean(summed_tonnes_scaled_byreg),.(survey_unit)][,yearly_min_bypoint_avg.scaledacrossall:=mean(yearly_min_bypoint_avg.scaledacrossall),.(survey_unit)]

dissimilarity_covariates_dredge.dt_predictions_consistenttempfishinginreg[,pred_dissim := 
                                                                         predict(model_avg_delta4, se.fit = T, full = F, newdata = dissimilarity_covariates_dredge.dt_predictions_consistenttempfishinginreg)[[1]]][,pred_se :=
                                                                                                                                                                                                                 predict(model_avg_delta4, se.fit = T, full = F, newdata = dissimilarity_covariates_dredge.dt_predictions_consistenttempfishinginreg)[[2]]]
Warning: argument 'full' ignoredWarning: argument 'full' ignored
#and then with consistent temp and fishing across regions (mean of both fishing and temp)
dissimilarity_covariates_dredge.dt_predictions_consistenttempfishing <- copy(dissimilarity_covariates_dredge.dt)
dissimilarity_covariates_dredge.dt_predictions_consistenttempfishing[,summed_tonnes_scaled_byreg:=mean(summed_tonnes_scaled_byreg)][,yearly_min_bypoint_avg.scaledacrossall:=mean(yearly_min_bypoint_avg.scaledacrossall)]

dissimilarity_covariates_dredge.dt_predictions_consistenttempfishing[,pred_dissim := 
                                                                         predict(model_avg_delta4, se.fit = T, full = F, newdata = dissimilarity_covariates_dredge.dt_predictions_consistenttempfishing)[[1]]][,pred_se :=
                                                                                                                                                                                                                 predict(model_avg_delta4, se.fit = T, full = F, newdata = dissimilarity_covariates_dredge.dt_predictions_consistenttempfishing)[[2]]]
Warning: argument 'full' ignoredWarning: argument 'full' ignored
#FOR COLOR TO MATCH
#sort color link by survey name season
#alphabetical order
color_link_alpha <- setorder(color_link, survey_unit)

#exclude surveys we don't include
color_link_alpha <- color_link_alpha[survey_unit %in% unique(dissimilarity_covariates_dredge.dt_predictions$survey_unit),]

color_alpha_order <- color_link_alpha[,hex]
label_alpha_order <- color_link_alpha[,Survey_Name_Season]
  

#maintain temp and fishing
#plot
predicted_values_temp_fishing <- ggplot(dissimilarity_covariates_dredge.dt_predictions) +
  geom_point(aes(x = year, y = annual_dissimilarity_value, color = survey_unit)) +
  geom_line(aes(x = year, y = pred_dissim, color = survey_unit)) +
  geom_ribbon(aes(x = year, ymin = pred_dissim-pred_se, ymax = pred_dissim+pred_se, fill = survey_unit), alpha = 0.3) +
  scale_color_manual(values = color_alpha_order, labels = label_alpha_order, name = "Survey") +
  scale_fill_manual(values = color_alpha_order, labels = label_alpha_order, name = "Survey") +
  labs(x = "Year",y = "Average annual total\nBray Curtis dissimilarity") +
  ylim(0,1.5) +
  theme_classic() +
  ggtitle("Average model predictions")

#average temp and fishing for each region
predicted_values_temp_fishing_meantempfishinginsurvey <- ggplot(dissimilarity_covariates_dredge.dt_predictions_consistenttempfishinginreg) +
  geom_point(aes(x = year, y = annual_dissimilarity_value, color = survey_unit)) +
  geom_line(aes(x = year, y = pred_dissim, color = survey_unit)) +
  geom_ribbon(aes(x = year, ymin = pred_dissim-pred_se, ymax = pred_dissim+pred_se, fill = survey_unit), alpha = 0.3) +
  scale_color_manual(values = color_alpha_order, labels = label_alpha_order, name = "Survey") +
  scale_fill_manual(values = color_alpha_order, labels = label_alpha_order, name = "Survey") +
  labs(x = "Year",y = "Average annual total\nBray Curtis dissimilarity") +
  ylim(0,1.5) +
  theme_classic() +
  ggtitle("Average model predictions with mean\nsurvey temperature and fishing pressure")

#average temp and fishing across all regions
predicted_values_temp_fishing_meantempfishing <- ggplot(dissimilarity_covariates_dredge.dt_predictions_consistenttempfishing) +
  geom_point(aes(x = year, y = annual_dissimilarity_value, color = survey_unit)) +
  geom_line(aes(x = year, y = pred_dissim, color = survey_unit)) +
  geom_ribbon(aes(x = year, ymin = pred_dissim-pred_se, ymax = pred_dissim+pred_se, fill = survey_unit), alpha = 0.1) +
  scale_color_manual(values = color_alpha_order, labels = label_alpha_order, name = "Survey") +
  scale_fill_manual(values = color_alpha_order, labels = label_alpha_order, name = "Survey") +
  labs(x = "Year",y = "Average annual total\nBray Curtis dissimilarity") +
  ylim(0,1.5) +
  theme_classic() +
  ggtitle("Average model predictions with mean\novereall temperature and fishing pressure")

#merge plots
predicted_values_sbt_jaccard_fishing_merge <- cowplot::plot_grid(predicted_values_temp_fishing,
                                                 predicted_values_temp_fishing_meantempfishinginsurvey,
                                                 predicted_values_temp_fishing_meantempfishing,
                                                 ncol = 1)
Warning: Removed 27 rows containing missing values (`geom_line()`).Warning: no non-missing arguments to max; returning -InfWarning: no non-missing arguments to max; returning -Inf
ggsave(predicted_values_sbt_jaccard_fishing_merge, path = here::here("figures"), filename = "predicted_values_sbt_jaccard_fishing_merge.jpg", height = 30, width = 14)

Take dissimilarity values from random normal distribution for each year for each region, and then calculate slope (1000 times). Do this for: - Fishing and temperature vary interannually within surveys - Temperature is held constant (as mean over time series for a survey), but fishing varies (allows us to look at relative variance explained) - Fishing is held constant (as mean over time series for a survey), but temperature varies (allows us to look at relative variance explained) - Both fishing and temperature held constant (allows us to see role of other components of the model)

################################################################################
#full predictions
################################################################################
#table with predicted dissimilarity values and standard error of all predicted dissimilarity values (by year)
table <- dissimilarity_covariates_dredge.dt_predictions[,.(survey_unit, pred_dissim, pred_se, year)]
#0) make datatable to populate
  predicted_dissim_trends_rnormruns <- data.table()
#1) NEW PREDICTED VALUES FROM DISTRIBUTION
for (i in 1:1000){
  table[,rnorm_pred := rnorm(1, mean = pred_dissim, sd = pred_se),.(year, survey_unit)]
#2) CALCULATE LINEAR MODEL TO EXTRACT SURVEY SPECIFIC TREND VALUES
  jaccard_total_predicted_lm_singlerun <- lm(rnorm_pred ~ year*survey_unit,data = table)

  model_coefs_reduced_predictions_singlerun <- data.table(summary(jaccard_total_predicted_lm_singlerun)$coefficients)
  model_coefs_reduced_predictions_singlerun[,var := rownames(summary(jaccard_total_predicted_lm_singlerun)$coefficients)]
  
  #limit to interactions only (check this if there are any model changes!) row 2 and rows 34:64
  model_coefs_reduced_predictions_singlerun <- model_coefs_reduced_predictions_singlerun[c(2,34:64),]
  
  #adjust survey unit name by deleting beginning of string
  model_coefs_reduced_predictions_singlerun[,survey_unit := substr(var, 17, str_length(var))][var == "year",survey_unit := "AI"]
  
  #calculate interaction coefficients
  AI_estimate <- model_coefs_reduced_predictions_singlerun[1,Estimate]
  model_coefs_reduced_predictions_singlerun[1,survey_unit_coefficient := AI_estimate]
  model_coefs_reduced_predictions_singlerun[2:32,survey_unit_coefficient := (AI_estimate + Estimate)]
  
  predicted_dissim_trends_rnormruns <- rbind(predicted_dissim_trends_rnormruns, model_coefs_reduced_predictions_singlerun[,.(survey_unit, survey_unit_coefficient)])
  
  print(i)
}
  
#reduce to mean and standard deviation
predicted_dissim_trends_rnormruns[,mean_dissim_coef:= mean(survey_unit_coefficient),survey_unit][,sd_dissim := sd(survey_unit_coefficient),.(survey_unit)]

predicted_dissim_trends_rnormruns.summary <- unique(predicted_dissim_trends_rnormruns[,.(survey_unit, mean_dissim_coef, sd_dissim)])

predicted_dissim_trends_rnormruns.summary[,pred_type := "full"]

################################################################################
#predictions with temp held constant and fishing still varying from year to year
################################################################################
#table with predicted dissimilarity values and standard error of all predicted dissimilarity values (by year)
table_constanttemp <- dissimilarity_covariates_dredge.dt_predictions_consistenttempinreg[,.(survey_unit, pred_dissim, pred_se, year)]
#0) make datatable to populate
  predicted_dissim_trends_rnormruns_constanttemp <- data.table()
#1) NEW PREDICTED VALUES FROM DISTRIBUTION
for (i in 1:1000){
  table_constanttemp[,rnorm_pred := rnorm(1, mean = pred_dissim, sd = pred_se),.(year, survey_unit)]
#2) CALCULATE LINEAR MODEL FOR SLOPE VALUES
  jaccard_total_predicted_lm_singlerun_constanttemp <- lm(rnorm_pred ~ year*survey_unit,data = table_constanttemp)

  model_coefs_reduced_predictions_singlerun_constanttemp <- data.table(summary(jaccard_total_predicted_lm_singlerun_constanttemp)$coefficients)
  model_coefs_reduced_predictions_singlerun_constanttemp[,var := rownames(summary(jaccard_total_predicted_lm_singlerun_constanttemp)$coefficients)]
  
  #limit to interactions only (check this if there are any model changes!) row 2 and rows 34:64
  model_coefs_reduced_predictions_singlerun_constanttemp <- model_coefs_reduced_predictions_singlerun_constanttemp[c(2,34:64),]
  
  #adjust survey unit name by deleting beginning of string
  model_coefs_reduced_predictions_singlerun_constanttemp[,survey_unit := substr(var, 17, str_length(var))][var == "year",survey_unit := "AI"]
  
  #calculate interaction coefficients
  AI_estimate <- model_coefs_reduced_predictions_singlerun_constanttemp[1,Estimate]
  model_coefs_reduced_predictions_singlerun_constanttemp[1,survey_unit_coefficient := AI_estimate]
  model_coefs_reduced_predictions_singlerun_constanttemp[2:32,survey_unit_coefficient := (AI_estimate + Estimate)]
  
  predicted_dissim_trends_rnormruns_constanttemp <- rbind(predicted_dissim_trends_rnormruns_constanttemp, model_coefs_reduced_predictions_singlerun_constanttemp[,.(survey_unit, survey_unit_coefficient)])
  
  print(i)
}
  
#reduce to mean and standard deviation
predicted_dissim_trends_rnormruns_constanttemp[,mean_dissim_coef:= mean(survey_unit_coefficient),survey_unit][,sd_dissim := sd(survey_unit_coefficient),.(survey_unit)]

predicted_dissim_trends_rnormrunsconstant_temp.summary <- unique(predicted_dissim_trends_rnormruns_constanttemp[,.(survey_unit, mean_dissim_coef, sd_dissim)])

predicted_dissim_trends_rnormrunsconstant_temp.summary[,pred_type := "temp_constant"]

predicted_dissim_trends_rnormruns.summary <- rbind(predicted_dissim_trends_rnormruns.summary, predicted_dissim_trends_rnormrunsconstant_temp.summary)

################################################################################
#predictions with fishing held constant (and temperature varying)
################################################################################
#table with predicted dissimilarity values and standard error of all predicted dissimilarity values (by year)
table_constantfishing <- dissimilarity_covariates_dredge.dt_predictions_consistentfishinginreg[,.(survey_unit, pred_dissim, pred_se, year)]
#0) make datatable to populate
  predicted_dissim_trends_rnormruns_constantfishing <- data.table()
#1) NEW PREDICTED VALUES FROM DISTRIBUTION
for (i in 1:1000){
  table_constantfishing[,rnorm_pred := rnorm(1, mean = pred_dissim, sd = pred_se),.(year, survey_unit)]
#2) CALCULATE LINEAR MODEL FOR SLOPE VALUES
  jaccard_total_predicted_lm_singlerun_constantfishing <- lm(rnorm_pred ~ year*survey_unit,data = table_constantfishing)

  model_coefs_reduced_predictions_singlerun_constantfishing <- data.table(summary(jaccard_total_predicted_lm_singlerun_constantfishing)$coefficients)
  model_coefs_reduced_predictions_singlerun_constantfishing[,var := rownames(summary(jaccard_total_predicted_lm_singlerun_constantfishing)$coefficients)]
  
  #limit to interactions only (check this if there are any model changes!) row 2 and rows 34:64
  model_coefs_reduced_predictions_singlerun_constantfishing <- model_coefs_reduced_predictions_singlerun_constantfishing[c(2,34:64),]
  
  #adjust survey unit name by deleting beginning of string
  model_coefs_reduced_predictions_singlerun_constantfishing[,survey_unit := substr(var, 17, str_length(var))][var == "year",survey_unit := "AI"]
  
  #calculate interaction coefficients
  AI_estimate <- model_coefs_reduced_predictions_singlerun_constantfishing[1,Estimate]
  model_coefs_reduced_predictions_singlerun_constantfishing[1,survey_unit_coefficient := AI_estimate]
  model_coefs_reduced_predictions_singlerun_constantfishing[2:32,survey_unit_coefficient := (AI_estimate + Estimate)]
  
  predicted_dissim_trends_rnormruns_constantfishing <- rbind(predicted_dissim_trends_rnormruns_constantfishing, model_coefs_reduced_predictions_singlerun_constantfishing[,.(survey_unit, survey_unit_coefficient)])
  
  print(i)
}
  
#reduce to mean and standard deviation
predicted_dissim_trends_rnormruns_constantfishing[,mean_dissim_coef:= mean(survey_unit_coefficient),survey_unit][,sd_dissim := sd(survey_unit_coefficient),.(survey_unit)]

predicted_dissim_trends_rnormrunsconstant_fishing.summary <- unique(predicted_dissim_trends_rnormruns_constantfishing[,.(survey_unit, mean_dissim_coef, sd_dissim)])

predicted_dissim_trends_rnormrunsconstant_fishing.summary[,pred_type := "fishing_constant"]

predicted_dissim_trends_rnormruns.summary <- rbind(predicted_dissim_trends_rnormruns.summary, predicted_dissim_trends_rnormrunsconstant_fishing.summary)


################################################################################
#predictions with both fishing and temperature held constant (variability goes to other factors we don't account for)
################################################################################
#table with predicted dissimilarity values and standard error of all predicted dissimilarity values (by year)
table_constanttempfishing <- dissimilarity_covariates_dredge.dt_predictions_consistenttempfishinginreg[,.(survey_unit, pred_dissim, pred_se, year)]
#0) make datatable to populate
  predicted_dissim_trends_rnormruns_constanttempfishing <- data.table()
#1) NEW PREDICTED VALUES FROM DISTRIBUTION
for (i in 1:1000){
  table_constanttempfishing[,rnorm_pred := rnorm(1, mean = pred_dissim, sd = pred_se),.(year, survey_unit)]
#2) CALCULATE LINEAR MODEL FOR SLOPE VALUES
  jaccard_total_predicted_lm_singlerun_constanttempfishing <- lm(rnorm_pred ~ year*survey_unit,data = table_constanttempfishing)

  model_coefs_reduced_predictions_singlerun_constanttempfishing <- data.table(summary(jaccard_total_predicted_lm_singlerun_constanttempfishing)$coefficients)
  model_coefs_reduced_predictions_singlerun_constanttempfishing[,var := rownames(summary(jaccard_total_predicted_lm_singlerun_constanttempfishing)$coefficients)]
  
  #limit to interactions only (check this if there are any model changes!) row 2 and rows 34:64
  model_coefs_reduced_predictions_singlerun_constanttempfishing <- model_coefs_reduced_predictions_singlerun_constanttempfishing[c(2,34:64),]
  
  #adjust survey unit name by deleting beginning of string
  model_coefs_reduced_predictions_singlerun_constanttempfishing[,survey_unit := substr(var, 17, str_length(var))][var == "year",survey_unit := "AI"]
  
  #calculate interaction coefficients
  AI_estimate <- model_coefs_reduced_predictions_singlerun_constanttempfishing[1,Estimate]
  model_coefs_reduced_predictions_singlerun_constanttempfishing[1,survey_unit_coefficient := AI_estimate]
  model_coefs_reduced_predictions_singlerun_constanttempfishing[2:32,survey_unit_coefficient := (AI_estimate + Estimate)]
  
  predicted_dissim_trends_rnormruns_constanttempfishing <- rbind(predicted_dissim_trends_rnormruns_constanttempfishing, model_coefs_reduced_predictions_singlerun_constanttempfishing[,.(survey_unit, survey_unit_coefficient)])
  
  print(i)
}
  
#reduce to mean and standard deviation
predicted_dissim_trends_rnormruns_constanttempfishing[,mean_dissim_coef:= mean(survey_unit_coefficient),survey_unit][,sd_dissim := sd(survey_unit_coefficient),.(survey_unit)]

predicted_dissim_trends_rnormrunsconstant_tempfishing.summary <- unique(predicted_dissim_trends_rnormruns_constanttempfishing[,.(survey_unit, mean_dissim_coef, sd_dissim)])

predicted_dissim_trends_rnormrunsconstant_tempfishing.summary[,pred_type := "fishing_and_temp_constant"]

predicted_dissim_trends_rnormruns.summary <- rbind(predicted_dissim_trends_rnormruns.summary, predicted_dissim_trends_rnormrunsconstant_tempfishing.summary)

Plotting observed vs predicted


jaccard_fishing_temp_model_observed_predicted_dt <- jaccard_total_coefs.r[predicted_dissim_trends_rnormruns.summary, on = "survey_unit"]

jaccard_fishing_temp_model_observed_predicted_dt[,pred_lower := mean_dissim_coef-sd_dissim][,pred_upper := mean_dissim_coef+sd_dissim]

#FULL MODEL, both temperature and fishing are allowed to vary
jaccard_fishing_temp_model_observed_predicted_lm <- lm(survey_unit_coefficient ~ mean_dissim_coef, data = jaccard_fishing_temp_model_observed_predicted_dt[pred_type == "full"])
summary(jaccard_fishing_temp_model_observed_predicted_lm) #R^2 0.42

Call:
lm(formula = survey_unit_coefficient ~ mean_dissim_coef, data = jaccard_fishing_temp_model_observed_predicted_dt[pred_type == 
    "full"])

Residuals:
       Min         1Q     Median         3Q        Max 
-0.0040158 -0.0004766 -0.0001640  0.0003970  0.0030020 

Coefficients:
                   Estimate Std. Error t value Pr(>|t|)    
(Intercept)      -2.510e-06  2.463e-04  -0.010    0.992    
mean_dissim_coef  1.118e+00  2.494e-01   4.483 9.99e-05 ***
---
Signif. codes:  0 ā€˜***’ 0.001 ā€˜**’ 0.01 ā€˜*’ 0.05 ā€˜.’ 0.1 ā€˜ ’ 1

Residual standard error: 0.001385 on 30 degrees of freedom
Multiple R-squared:  0.4011,    Adjusted R-squared:  0.3812 
F-statistic: 20.09 on 1 and 30 DF,  p-value: 9.994e-05
(jaccard_fishing_temp_model_observed_predicted <- ggplot(jaccard_fishing_temp_model_observed_predicted_dt[pred_type == "full"]) +
  geom_errorbar(aes(x = mean_dissim_coef, ymin = lwr, ymax = upr), color = "lightgrey", linewidth = 0.4) +
  geom_errorbarh(aes(y = survey_unit_coefficient, xmin = mean_dissim_coef-sd_dissim, xmax = mean_dissim_coef+sd_dissim), color = "lightgrey", linewidth = 0.4) +
  geom_point(aes(y = survey_unit_coefficient, x = mean_dissim_coef)) +
  geom_smooth(aes(y = survey_unit_coefficient, x = mean_dissim_coef), color = "darkgrey",linetype = "dotted", method = "lm") +
  geom_abline(aes(slope = 1, intercept = 0)) +
  lims(x = c(min(jaccard_fishing_temp_model_observed_predicted_dt$pred_lower),max(jaccard_fishing_temp_model_observed_predicted_dt$pred_upper))) +
  labs(y = "Observed β-diversity trend",x = "Predicted β-diversity trend\n") +
  theme_classic()
)


#fishing constant (fishing constant; temperature varies only)
jaccard_fishing_constant_model_observed_predicted_lm <- lm(survey_unit_coefficient ~ mean_dissim_coef, data = jaccard_fishing_temp_model_observed_predicted_dt[pred_type == "fishing_constant"])
summary(jaccard_fishing_constant_model_observed_predicted_lm) 

Call:
lm(formula = survey_unit_coefficient ~ mean_dissim_coef, data = jaccard_fishing_temp_model_observed_predicted_dt[pred_type == 
    "fishing_constant"])

Residuals:
       Min         1Q     Median         3Q        Max 
-0.0037145 -0.0009269  0.0001445  0.0012234  0.0026883 

Coefficients:
                   Estimate Std. Error t value Pr(>|t|)   
(Intercept)      -0.0002055  0.0002974  -0.691  0.49495   
mean_dissim_coef  1.5387839  0.5107700   3.013  0.00522 **
---
Signif. codes:  0 ā€˜***’ 0.001 ā€˜**’ 0.01 ā€˜*’ 0.05 ā€˜.’ 0.1 ā€˜ ’ 1

Residual standard error: 0.001568 on 30 degrees of freedom
Multiple R-squared:  0.2323,    Adjusted R-squared:  0.2067 
F-statistic: 9.076 on 1 and 30 DF,  p-value: 0.005221
#Temperature as a predictor, not fishing = R^2 = 0.28 (drop in 12% of variance explained when you lose fishing as predictor)

(jaccard_fishing_constant_model_observed_predicted <- ggplot(jaccard_fishing_temp_model_observed_predicted_dt[pred_type == "fishing_constant"]) +
geom_errorbar(aes(x = mean_dissim_coef, ymin = lwr, ymax = upr), color = "lightgrey", linewidth = 0.4) +
  geom_errorbarh(aes(y = survey_unit_coefficient, xmin = mean_dissim_coef-sd_dissim, xmax = mean_dissim_coef+sd_dissim), color = "lightgrey", linewidth = 0.4) +
  geom_point(aes(y = survey_unit_coefficient, x = mean_dissim_coef)) +
    geom_smooth(aes(y = survey_unit_coefficient, x = mean_dissim_coef), color = "darkgrey",linetype = "dotted", method = "lm") +
  geom_abline(aes(slope = 1, intercept = 0)) +
      lims(x = c(min(jaccard_fishing_temp_model_observed_predicted_dt$pred_lower),max(jaccard_fishing_temp_model_observed_predicted_dt$pred_upper))) +
  labs(y = "Observed β-diversity trend",x = "Predicted β-diversity trend\n(temperature varies fishing constant)") +
  theme_classic()
)


#temp constant (fishing only; temperature constant)
jaccard_temperature_constant_model_observed_predicted_lm <- lm(survey_unit_coefficient ~ mean_dissim_coef, data = jaccard_fishing_temp_model_observed_predicted_dt[pred_type == "temp_constant"])
summary(jaccard_temperature_constant_model_observed_predicted_lm) #0.18 Drop in 22% of variance explained when you lose temperature as a predictor

Call:
lm(formula = survey_unit_coefficient ~ mean_dissim_coef, data = jaccard_fishing_temp_model_observed_predicted_dt[pred_type == 
    "temp_constant"])

Residuals:
       Min         1Q     Median         3Q        Max 
-0.0037086 -0.0007951 -0.0000619  0.0004231  0.0043027 

Coefficients:
                  Estimate Std. Error t value Pr(>|t|)  
(Intercept)      0.0001087  0.0002877   0.378   0.7083  
mean_dissim_coef 0.6701402  0.2673702   2.506   0.0178 *
---
Signif. codes:  0 ā€˜***’ 0.001 ā€˜**’ 0.01 ā€˜*’ 0.05 ā€˜.’ 0.1 ā€˜ ’ 1

Residual standard error: 0.001627 on 30 degrees of freedom
Multiple R-squared:  0.1731,    Adjusted R-squared:  0.1456 
F-statistic: 6.282 on 1 and 30 DF,  p-value: 0.01785
(jaccard_temperature_constant_model_observed_predicted <- ggplot(jaccard_fishing_temp_model_observed_predicted_dt[pred_type == "temp_constant"]) +
  geom_errorbar(aes(x = mean_dissim_coef, ymin = lwr, ymax = upr), color = "lightgrey", linewidth = 0.4) +
  geom_errorbarh(aes(y = survey_unit_coefficient, xmin = mean_dissim_coef-sd_dissim, xmax = mean_dissim_coef+sd_dissim), color = "lightgrey", linewidth = 0.4) +
  geom_point(aes(y = survey_unit_coefficient, x = mean_dissim_coef)) +
    geom_smooth(aes(y = survey_unit_coefficient, x = mean_dissim_coef), color = "darkgrey",linetype = "dotted", method = "lm") +
  geom_abline(aes(slope = 1, intercept = 0)) +
      lims(x = c(min(jaccard_fishing_temp_model_observed_predicted_dt$pred_lower),max(jaccard_fishing_temp_model_observed_predicted_dt$pred_upper))) +
  labs(y = "Observed β-diversity trend",x = "Predicted β-diversity trend\n(fishing varies temperature constant)") +
  theme_classic()
)


#both temperature and fish held constant
jaccard_fishing_temp_model_observed_predicted_tempfishconstantinsurvey_lm <- lm(survey_unit_coefficient ~ mean_dissim_coef, data = jaccard_fishing_temp_model_observed_predicted_dt[pred_type == "fishing_and_temp_constant"])
summary(jaccard_fishing_temp_model_observed_predicted_tempfishconstantinsurvey_lm) #%11 

Call:
lm(formula = survey_unit_coefficient ~ mean_dissim_coef, data = jaccard_fishing_temp_model_observed_predicted_dt[pred_type == 
    "fishing_and_temp_constant"])

Residuals:
       Min         1Q     Median         3Q        Max 
-0.0035992 -0.0007889 -0.0002449  0.0009627  0.0039403 

Coefficients:
                   Estimate Std. Error t value Pr(>|t|)
(Intercept)      -1.051e-05  3.211e-04  -0.033    0.974
mean_dissim_coef  1.166e+00  8.503e-01   1.372    0.180

Residual standard error: 0.001736 on 30 degrees of freedom
Multiple R-squared:  0.05902,   Adjusted R-squared:  0.02766 
F-statistic: 1.882 on 1 and 30 DF,  p-value: 0.1803
(jaccard_fishing_temp_model_observed_predicted_tempfishconstantinsurvey <- ggplot(jaccard_fishing_temp_model_observed_predicted_dt[pred_type == "fishing_and_temp_constant"]) +
geom_errorbar(aes(x = mean_dissim_coef, ymin = lwr, ymax = upr), color = "lightgrey", linewidth = 0.4) +
  geom_errorbarh(aes(y = survey_unit_coefficient, xmin = mean_dissim_coef-sd_dissim, xmax = mean_dissim_coef+sd_dissim), color = "lightgrey", linewidth = 0.4) +
  geom_point(aes(y = survey_unit_coefficient, x = mean_dissim_coef)) +
    geom_smooth(aes(y = survey_unit_coefficient, x = mean_dissim_coef), color = "darkgrey",linetype = "dotted", method = "lm")+
  geom_abline(aes(slope = 1, intercept = 0)) +
      lims(x = c(min(jaccard_fishing_temp_model_observed_predicted_dt$pred_lower),max(jaccard_fishing_temp_model_observed_predicted_dt$pred_upper))) +
  labs(y = "Observed β-diversity trend",x = "Predicted β-diversity trend\n(fishing and temperature constant)") +
  theme_classic()
)


#merge
jaccard_fishing_sbt_model_observed_predicted_merge <- plot_grid(jaccard_fishing_temp_model_observed_predicted + theme(plot.margin = unit(c(0.1,0.3,0.1,0.1),"cm")),
                                                                     jaccard_fishing_constant_model_observed_predicted + theme(plot.margin = unit(c(0.1,0.3,0.1,0.1),"cm")),
                                                                     jaccard_temperature_constant_model_observed_predicted + theme(plot.margin = unit(c(0.1,0.3,0.1,0.1),"cm")),
                                                                     jaccard_fishing_temp_model_observed_predicted_tempfishconstantinsurvey + theme(plot.margin = unit(c(0.1,0.3,0.1,0.1),"cm")), ncol = 2, labels = c("a.","b.","c.","d."))
`geom_smooth()` using formula = 'y ~ x'`geom_smooth()` using formula = 'y ~ x'`geom_smooth()` using formula = 'y ~ x'`geom_smooth()` using formula = 'y ~ x'
ggsave(jaccard_fishing_sbt_model_observed_predicted_merge, path = here::here("figures"),filename = "jaccard_fishing_sbt_model_observed_predicted_merge.jpg", height =6, width = 8)

NA
NA

Let’s visualize model coefficients with temperature and fishing (similar to figure 2) model_avg_values

model_avg_values

interaction_avg_model_coef <- model_avg_values[c(5,37:99),.(coef_name, coef, se)]

#insert AI
interaction_avg_model_coef[1:2,survey_unit := "AI"][1:2,coef_true := coef][1:2,predictor := c("Relative fishing catch","Minimum temperature")]

#Other summed_tonnes_scaled_byreg
interaction_avg_model_coef[3:33,survey_unit := substr(coef_name, 39, str_length(coef_name))][3:33,coef_true := interaction_avg_model_coef[1,coef_true]+coef][3:33,predictor := "Relative fishing catch"]

#Other yearly_min_bypoint_avg.scaledacrossall
interaction_avg_model_coef[34:64,survey_unit := substr(coef_name, str_length("survey_unit")+1, str_length(coef_name)-str_length("yearly_min_bypoint_avg.scaledacrossall")-1)][34:64,coef_true := interaction_avg_model_coef[2,coef_true]+coef][34:64,predictor := "Minimum temperature"]

#reorder temperature and fishing
interaction_avg_model_coef[,predictor := factor(predictor, levels = c("Minimum temperature","Relative fishing catch"))]

#link for full survey name
interaction_avg_model_coef <- color_link[interaction_avg_model_coef, on = "survey_unit"]

#reorder by survey_unit
interaction_avg_model_coef[,Survey_Name_Season := reorder(Survey_Name_Season, survey_unit, decreasing = TRUE)]
Warning: argument is not numeric or logical: returning NAWarning: argument is not numeric or logical: returning NAWarning: argument is not numeric or logical: returning NAWarning: argument is not numeric or logical: returning NAWarning: argument is not numeric or logical: returning NAWarning: argument is not numeric or logical: returning NAWarning: argument is not numeric or logical: returning NAWarning: argument is not numeric or logical: returning NAWarning: argument is not numeric or logical: returning NAWarning: argument is not numeric or logical: returning NAWarning: argument is not numeric or logical: returning NAWarning: argument is not numeric or logical: returning NAWarning: argument is not numeric or logical: returning NAWarning: argument is not numeric or logical: returning NAWarning: argument is not numeric or logical: returning NAWarning: argument is not numeric or logical: returning NAWarning: argument is not numeric or logical: returning NAWarning: argument is not numeric or logical: returning NAWarning: argument is not numeric or logical: returning NAWarning: argument is not numeric or logical: returning NAWarning: argument is not numeric or logical: returning NAWarning: argument is not numeric or logical: returning NAWarning: argument is not numeric or logical: returning NAWarning: argument is not numeric or logical: returning NAWarning: argument is not numeric or logical: returning NAWarning: argument is not numeric or logical: returning NAWarning: argument is not numeric or logical: returning NAWarning: argument is not numeric or logical: returning NAWarning: argument is not numeric or logical: returning NAWarning: argument is not numeric or logical: returning NAWarning: argument is not numeric or logical: returning NAWarning: argument is not numeric or logical: returning NA
#mark significance
interaction_avg_model_coef[,Significant := ifelse((coef_true-se > 0 & coef_true+se > 0) | (coef_true-se < 0 & coef_true+se < 0),T,F)]


#Plot both
sbt_fishing_avg_model_coef <- ggplot() +
  geom_hline(yintercept = 0, linetype = "dotted") +
geom_point(data = interaction_avg_model_coef, aes(x = Survey_Name_Season, y = coef_true, color = Significant)) +  
geom_errorbar(data = interaction_avg_model_coef, aes(x = Survey_Name_Season, ymin = coef_true-se, ymax = coef_true+se, color = Significant), width = 0) +
  scale_color_manual(values = c("darkgrey","black")) +
facet_wrap(~predictor, scales = "free_x") +
scale_x_discrete(limits = rev) +
  labs(y = "Coefficient", x = "") +
coord_flip() +
theme_classic()
  

Plot all other coefficients in averaged model

model_avg_values.nonfishortemp <- model_avg_values[c(2,3,4,100:104),]

#mark significance
model_avg_values.nonfishortemp[,Significant := ifelse((coef-se > 0 & coef+se > 0) | (coef-se < 0 & coef+se < 0),T,F)]

#more helpful names for variables
model_avg_values.nonfishortemp[,Variable := c("Area","Julian day","Species count","Number of tows","Latitude range","Depth","Latitude","Depth range")]

#make factor with order
model_avg_values.nonfishortemp[,Variable := factor(Variable, levels = c("Area","Julian day","Species count","Number of tows","Depth","Depth range","Latitude","Latitude range"))]


#plot
all_avg_model_coef <- ggplot() + 
geom_point(data = model_avg_values.nonfishortemp, aes(x = Variable, y = coef, color = Significant)) +  
geom_errorbar(data = model_avg_values.nonfishortemp, aes(x = Variable, ymin = coef-se, ymax = coef+se, color = Significant), width = 0) +
  scale_color_manual(values = c("darkgrey","black")) +
geom_hline(yintercept = 0) +
scale_x_discrete(limits = rev) +
  labs(y = "Coefficient", x = "\n\n\n") +
coord_flip() +
theme_classic()

#plot
all_but_lat_avg_model_coef <- ggplot() + 
geom_point(data = model_avg_values.nonfishortemp[Variable == "Latitude"], aes(x = Variable, y = coef, color = Significant)) +  
geom_errorbar(data = model_avg_values.nonfishortemp[Variable == "Latitude"], aes(x = Variable, ymin = coef-se, ymax = coef+se, color = Significant), width = 0) +
  scale_color_manual(values = c("darkgrey","black")) +
geom_hline(yintercept = 0) +
scale_x_discrete(limits = rev) +
  labs(y = "Coefficient", x = "Model variable") +
coord_flip() +
theme_classic()

#plot
lat_avg_model_coef <- ggplot() + 
geom_point(data = model_avg_values.nonfishortemp[Variable != "Latitude"], aes(x = Variable, y = coef, color = Significant)) +  
geom_errorbar(data = model_avg_values.nonfishortemp[Variable != "Latitude"], aes(x = Variable, ymin = coef-se, ymax = coef+se, color = Significant), width = 0) +
  scale_color_manual(values = c("darkgrey","black")) +
geom_hline(yintercept = 0) +
scale_x_discrete(limits = rev) +
  labs(y = "Coefficient", x = "Model variable") +
coord_flip() +
theme_classic()

#merge into single plot

model_coef_summary_sbt_jaccard <- cowplot::plot_grid(sbt_fishing_avg_model_coef+theme(legend.position = "null", axis.title.x = element_blank()),all_avg_model_coef+theme(legend.position = "null"), ncol = 1, labels = c("  a.                                                      b.","        c."), label_y = 0.99, rel_heights = c(3,1))

ggsave(model_coef_summary_sbt_jaccard, path = here::here("figures"),filename = "model_coef_summary_sbt_jaccard.jpg", height = 6.5, width = 8, unit = "in")
LS0tCnRpdGxlOiAiTW9kZWwgYW5udWFsIGRpc3NpbWlsYXJpdHkgd2l0aCB0ZW1wZXJhdHVyZSwgZmlzaGluZywgYW5kIHN1cnZleSBpZGVudGl0eSIKb3V0cHV0OiBodG1sX25vdGVib29rCmF1dGhvcjogWm/DqyBKLiBLaXRjaGVsCmRhdGU6IE1heSA2LCAyMDI1Ci0tLQoKU2NyaXB0IDggZm9yIEtpdGNoZWwgZXQgYWwuIDIwMjQgaW4gcHJlcCB0YXhvbm9taWMgZGl2ZXJzaXR5IG1hbnVzY3JpcHQuCgoKYGBge3Igc2V0dXB9CmxpYnJhcnkoZGF0YS50YWJsZSkKbGlicmFyeShNdU1JbikKbGlicmFyeShnZ3Bsb3QyKQpsaWJyYXJ5KGNvd3Bsb3QpCmxpYnJhcnkobG1lNCkKbGlicmFyeShzdHJpbmdyKQpgYGAKCiMjI1ByZWRpY3RzIGFubnVhbCBkaXNzaW1pbGFyaXR5IHdpdGggYW5udWFsIGNoYXJhY3RlcmlzdGljcywgdGVtcGVyYXR1cmUgYW5kIGZpc2hpbmcgdmFsdWVzCgpQdWxsIGluCi0gcmVnaW9uIGFyZWFzIChpZiBub3QgYWxyZWFkeSBsb2FkZWQpCi0gcmVnaW9uIGNoYXJhY3RlcmlzdGljcyAoaWYgbm90IGFscmVhZHkgbG9hZGVkKTsgc2F2ZVJEUyhGaXNoR2xvYl9yaWNobmVzc195ZWFyX3N1cnZleSwgZmlsZSA9IGhlcmU6OmhlcmUoIm91dHB1dCIsIkZpc2hHbG9iX3JpY2huZXNzX3llYXJfc3VydmV5LlJkcyIpKQotIGZpc2hpbmcgKGlmIG5vdCBhbHJlYWR5IGxvYWRlZCkKLSB0ZW1wIChpZiBub3QgYWxyZWFkeSBsb2FkZWQpCgoKCmBgYHtyfQojcGh5c2ljYWwgYXJlYSBieSB5ZWFyCnJlZ2lvbl9hcmVhX2J5eWVhciA8LSBmcmVhZChoZXJlOjpoZXJlKCJvdXRwdXQiLCJyZWdpb25fYXJlYV9ieXllYXIuY3N2IikpCgojbWVyZ2VkIGZpc2hpbmcsIHRlbXAsIGRpc3NpbWlsYXJpdGllcwpkaXNzaW1pbGFyaXRpZXNfdGVtcF9maXNoaW5nIDwtIGZyZWFkKGhlcmU6OmhlcmUoIm91dHB1dCIsImRpc3NpbWlsYXJpdGllc190ZW1wX2Zpc2hpbmcuY3N2IikpCgojY29tYmluZQpkaXNzaW1pbGFyaXRpZXNfdGVtcF9maXNoaW5nX2FyZWEgPC0gZGlzc2ltaWxhcml0aWVzX3RlbXBfZmlzaGluZ1tyZWdpb25fYXJlYV9ieXllYXIsIG9uID0gYygic3VydmV5X3VuaXQiLCJ5ZWFyIildCgojb25seSBqYWNjYXJkIGZvciB0aGVzZSBhbmFseXNlcwpkaXNzaW1pbGFyaXRpZXNfdGVtcF9maXNoaW5nX2FyZWEuamFjY2FyZCA8LSBkaXNzaW1pbGFyaXRpZXNfdGVtcF9maXNoaW5nX2FyZWFbZGlzc2ltaWxhcml0eV9tZXRyaWMgPT0gImphY2NhcmRfZGlzc2ltaWxhcml0eV90b3RhbCIsXQpgYGAKCkFkZCBpbiBhdmVyYWdlIEp1bGlhbiBkYXkKYGBge3J9CiNsb2FkIHVwIGp1bGlhbiBkYXlzCmRhdGVzX3JlZ2lvbnMgPC0gcmVhZFJEUyhoZXJlOjpoZXJlKCJvdXRwdXQiLCJkYXRlc19yZWdpb25zLnJkcyIpKQoKI3NpbXBsaWZ5CmRhdGVzX3JlZ2lvbnMuYW5udWFsIDwtIHVuaXF1ZShkYXRlc19yZWdpb25zWywuKHN1cnZleV91bml0LCB5ZWFyLCBhdmdfanVsaWFuX2FubnVhbCldKQoKI21lcmdlCmRpc3NpbWlsYXJpdGllc190ZW1wX2Zpc2hpbmdfYXJlYS5qYWNjYXJkIDwtIGRhdGVzX3JlZ2lvbnMuYW5udWFsW2Rpc3NpbWlsYXJpdGllc190ZW1wX2Zpc2hpbmdfYXJlYS5qYWNjYXJkLCBvbiA9IGMoInN1cnZleV91bml0IiwieWVhciIpXQpgYGAKCiAKUHVsbCBpbiBwYWxldHRlIGFuZCBuYW1lIGhlbHBlcgpgYGB7cn0Kc291cmNlKGhlcmU6OmhlcmUoImFuYWx5c2lzX2NvZGUiLCJjb2xvcl9saW5rcy5SIikpCmBgYAoKUHVsbCBpbiBvYnNlcnZlZCB0cmVuZCB2YWx1ZXMKYGBge3J9CmphY2NhcmRfdG90YWxfY29lZnMuciA8LSBmcmVhZChoZXJlOjpoZXJlKCJvdXRwdXQiLCJqYWNjYXJkX3RvdGFsX2NvZWZzLnIuY3N2IikpCmBgYAoKUGxvdCBmaXNoaW5nIGFuZCB0ZW1wZXJhdHVyZSB2cy4gdGltZSBmb3IgYWxsIHJlZ2lvbnMKYGBge3J9CiMjIyMjIyNURU1QRVJBVFVSRQoKI3NldCBvcmRlciBieSBzdXJ2ZXkgdW5pdCBmb3IgcGxvdHRpbmcKYWxsX3N1cnZleXMgPC0gbGV2ZWxzKGFzLmZhY3RvcihkaXNzaW1pbGFyaXRpZXNfdGVtcF9maXNoaW5nX2FyZWEuamFjY2FyZCRzdXJ2ZXlfdW5pdCkpCnNldG9yZGVyKGRpc3NpbWlsYXJpdGllc190ZW1wX2Zpc2hpbmdfYXJlYS5qYWNjYXJkLCBzdXJ2ZXlfdW5pdCkKCmRpc3NpbWlsYXJpdGllc190ZW1wX2Zpc2hpbmdfYXJlYS5qYWNjYXJkWyxTdXJ2ZXlfTmFtZV9TZWFzb246PWZhY3RvcihTdXJ2ZXlfTmFtZV9TZWFzb24sIGxldmVscyA9IHVuaXF1ZShkaXNzaW1pbGFyaXRpZXNfdGVtcF9maXNoaW5nX2FyZWEuamFjY2FyZCRTdXJ2ZXlfTmFtZV9TZWFzb24pLCBvcmRlcmVkID0gVCldCgooc2J0X3RpbWVfc3VydmV5X2ZhY2V0XzFfMjAgPC0gZ2dwbG90KGRhdGEgPSBkaXNzaW1pbGFyaXRpZXNfdGVtcF9maXNoaW5nX2FyZWEuamFjY2FyZFtzdXJ2ZXlfdW5pdCAlaW4lIGFsbF9zdXJ2ZXlzWzE6MjBdICYgeWVhciA+IDE5NzldKSArCiAgbGFicyh5ID0gIk1lYW4gYm90dG9tIHRlbXBlcmF0dXJlICjLmkMpIiwgIHggPSAiWWVhciIpICsKICBnZW9tX3BvaW50KGFlcyh5ID0gYXMubnVtZXJpYyh5ZWFybHlfbWVhbl9ieXBvaW50X2F2ZyksIHggPSB5ZWFyKSwgYWxwaGEgPSAwLjMpICsKICBnZW9tX3Ntb290aChhZXMoeSA9IGFzLm51bWVyaWMoeWVhcmx5X21lYW5fYnlwb2ludF9hdmcpLCB4ID0geWVhciksIG1ldGhvZCA9ICJsbSIpICsKICBzY2FsZV94X2NvbnRpbnVvdXMoYnJlYWtzID0gfiBheGlzVGlja3MoLiwgbG9nID0gRkFMU0UpKSArCiAgdGhlbWVfY2xhc3NpYygpICsKICB0aGVtZShheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dChzaXplID0gNykpICsKICBmYWNldF93cmFwKH5TdXJ2ZXlfTmFtZV9TZWFzb24sIHNjYWxlcz0gImZyZWUiLCBuY29sID0gNCkpCgpnZ3NhdmUoc2J0X3RpbWVfc3VydmV5X2ZhY2V0XzFfMjAsIHBhdGggPSBoZXJlOjpoZXJlKCJmaWd1cmVzIiksIGZpbGVuYW1lID0gInRlbXBfdGltZV9zdXJ2ZXlfZmFjZXRfMV8yMC5qcGciLCBoZWlnaHQgPSAxMiwgd2lkdGggPTkpCgooc2J0X3RpbWVfc3VydmV5X2ZhY2V0XzIxXzM0IDwtIGdncGxvdChkYXRhID0gZGlzc2ltaWxhcml0aWVzX3RlbXBfZmlzaGluZ19hcmVhLmphY2NhcmRbc3VydmV5X3VuaXQgJWluJSBhbGxfc3VydmV5c1syMTozNF0gJiB5ZWFyID4gMTk3OV0pICsKICBsYWJzKHkgPSAiTWVhbiBib3R0b20gdGVtcGVyYXR1cmUgKMuaQykiLCAgeCA9ICJZZWFyIikgKwogIGdlb21fcG9pbnQoYWVzKHkgPSBhcy5udW1lcmljKHllYXJseV9tZWFuX2J5cG9pbnRfYXZnKSwgeCA9IHllYXIpLCBhbHBoYSA9IDAuMykgKwogIGdlb21fc21vb3RoKGFlcyh5ID0gYXMubnVtZXJpYyh5ZWFybHlfbWVhbl9ieXBvaW50X2F2ZyksIHggPSB5ZWFyKSwgbWV0aG9kID0gImxtIikgKwogIHNjYWxlX3hfY29udGludW91cyhicmVha3MgPSB+IGF4aXNUaWNrcyguLCBsb2cgPSBGQUxTRSkpICsKICB0aGVtZV9jbGFzc2ljKCkgKwogIHRoZW1lKGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KHNpemUgPSA3KSkgKwogIGZhY2V0X3dyYXAoflN1cnZleV9OYW1lX1NlYXNvbiwgc2NhbGVzPSAiZnJlZSIsIG5jb2wgPSA0KSkKCmdnc2F2ZShzYnRfdGltZV9zdXJ2ZXlfZmFjZXRfMjFfMzQsIHBhdGggPSBoZXJlOjpoZXJlKCJmaWd1cmVzIiksIGZpbGVuYW1lID0gInNidF90aW1lX3N1cnZleV9mYWNldF8yMV8zNC5qcGciLCBoZWlnaHQgPSAxMiwgd2lkdGggPTkpCgojIyMjIyMjRklTSElORwoKZGlzc2ltaWxhcml0aWVzX3RlbXBfZmlzaGluZ19hcmVhLmphY2NhcmQuY2MgPC0gZGlzc2ltaWxhcml0aWVzX3RlbXBfZmlzaGluZ19hcmVhLmphY2NhcmRbY29tcGxldGUuY2FzZXMoZGlzc2ltaWxhcml0aWVzX3RlbXBfZmlzaGluZ19hcmVhLmphY2NhcmRbLHN1bW1lZF90b25uZXNfc2NhbGVkX2J5cmVnXSksXQoKKGZpc2hpbmdfdGltZV9zdXJ2ZXlfZmFjZXRfMV8yMCA8LSBnZ3Bsb3QoZGF0YSA9IGRpc3NpbWlsYXJpdGllc190ZW1wX2Zpc2hpbmdfYXJlYS5qYWNjYXJkLmNjW3N1cnZleV91bml0ICVpbiUgYWxsX3N1cnZleXNbMToyMF0gJiB5ZWFyID4gMTk3OV0pICsKICBsYWJzKHkgPSAiUmVsYXRpdmUgZmlzaGluZyBjYXRjaCIsICB4ID0gIlllYXIiKSArCiAgZ2VvbV9wb2ludChhZXMoeSA9IHN1bW1lZF90b25uZXNfc2NhbGVkX2J5cmVnLCB4ID0geWVhciksIGFscGhhID0gMC4zKSArCiAgZ2VvbV9zbW9vdGgoYWVzKHkgPSBzdW1tZWRfdG9ubmVzX3NjYWxlZF9ieXJlZywgeCA9IHllYXIpLCBtZXRob2QgPSAibG0iKSArCiAgc2NhbGVfeF9jb250aW51b3VzKGJyZWFrcyA9IH4gYXhpc1RpY2tzKC4sIGxvZyA9IEZBTFNFKSkgKwogIHRoZW1lX2NsYXNzaWMoKSArCiAgdGhlbWUoYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoc2l6ZSA9IDcpKSArCiAgZmFjZXRfd3JhcCh+U3VydmV5X05hbWVfU2Vhc29uLCBzY2FsZXM9ICJmcmVlIiwgbmNvbCA9IDQpKQoKZ2dzYXZlKGZpc2hpbmdfdGltZV9zdXJ2ZXlfZmFjZXRfMV8yMCwgcGF0aCA9IGhlcmU6OmhlcmUoImZpZ3VyZXMiKSwgZmlsZW5hbWUgPSAiZmlzaGluZ190aW1lX3N1cnZleV9mYWNldF8xXzIwLmpwZyIsIGhlaWdodCA9IDEyLCB3aWR0aCA9OSkKCihmaXNoaW5nX3RpbWVfc3VydmV5X2ZhY2V0XzIxXzM0IDwtIGdncGxvdChkYXRhID0gZGlzc2ltaWxhcml0aWVzX3RlbXBfZmlzaGluZ19hcmVhLmphY2NhcmQuY2Nbc3VydmV5X3VuaXQgJWluJSBhbGxfc3VydmV5c1tjKDIxOjM0KV0gJiB5ZWFyID4gMTk3OV0pICsKICBsYWJzKHkgPSAiUmVsYXRpdmUgZmlzaGluZyBjYXRjaCIsICB4ID0gIlllYXIiKSArCiAgZ2VvbV9wb2ludChhZXMoeSA9IHN1bW1lZF90b25uZXNfc2NhbGVkX2J5cmVnLCB4ID0geWVhciksIGFscGhhID0gMC4zKSArCiAgZ2VvbV9zbW9vdGgoYWVzKHkgPSBzdW1tZWRfdG9ubmVzX3NjYWxlZF9ieXJlZywgeCA9IHllYXIpLCBtZXRob2QgPSAibG0iKSArCiAgc2NhbGVfeF9jb250aW51b3VzKGJyZWFrcyA9IH4gYXhpc1RpY2tzKC4sIGxvZyA9IEZBTFNFKSkgKwogIHRoZW1lX2NsYXNzaWMoKSArCiAgdGhlbWUoYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoc2l6ZSA9IDcpKSArCiAgZmFjZXRfd3JhcCh+U3VydmV5X05hbWVfU2Vhc29uLCBzY2FsZXM9ICJmcmVlIiwgbmNvbCA9IDQpKQoKZ2dzYXZlKGZpc2hpbmdfdGltZV9zdXJ2ZXlfZmFjZXRfMjFfMzQsIHBhdGggPSBoZXJlOjpoZXJlKCJmaWd1cmVzIiksIGZpbGVuYW1lID0gImZpc2hpbmdfdGltZV9zdXJ2ZXlfZmFjZXRfMjFfMzQuanBnIiwgaGVpZ2h0ID0gMTIsIHdpZHRoID05KQoKCmBgYAoKUGxvdCBmaXNoaW5nIGFuZCB0ZW1wZXJhdHVyZSB2cy4gZGlzc2ltaWxhcml0eSBmb3IgYWxsIHJlZ2lvbnMKYGBge3J9CiMjIyMjTUVBTiBURU1QCihwcmVkc19zYnRfbWVhbl90ZW1wX3N1cnZleV9mYWNldF8xXzIwIDwtIGdncGxvdChkYXRhID0gZGlzc2ltaWxhcml0aWVzX3RlbXBfZmlzaGluZ19hcmVhLmphY2NhcmRbc3VydmV5X3VuaXQgJWluJSBhbGxfc3VydmV5c1sxOjIwXSAmIHllYXIgPiAxOTc5XSkgKwogIGxhYnMoeCA9ICJNZWFuIGJvdHRvbSB0ZW1wZXJhdHVyZSAoy5pDKSIsICB5ID0gIs6yLWRpdmVyc2l0eSIpICsKICBnZW9tX3BvaW50KGFlcyh4ID0gYXMubnVtZXJpYyh5ZWFybHlfbWVhbl9ieXBvaW50X2F2ZyksIHkgPSBhbm51YWxfZGlzc2ltaWxhcml0eV92YWx1ZSksIGFscGhhID0gMC4zKSArCiAgZ2VvbV9zbW9vdGgoYWVzKHggPSBhcy5udW1lcmljKHllYXJseV9tZWFuX2J5cG9pbnRfYXZnKSwgeSA9IGFubnVhbF9kaXNzaW1pbGFyaXR5X3ZhbHVlKSwgbWV0aG9kID0gImxtIikgKwogIGZhY2V0X3dyYXAoflN1cnZleV9OYW1lX1NlYXNvbiwgc2NhbGVzPSAiZnJlZSIsIG5jb2wgPSA0KSArCiAgdGhlbWVfY2xhc3NpYygpKQoKZ2dzYXZlKHByZWRzX3NidF9tZWFuX3RlbXBfc3VydmV5X2ZhY2V0XzFfMjAsIHBhdGggPSBoZXJlOjpoZXJlKCJmaWd1cmVzIiksIGZpbGVuYW1lID0gInByZWRzX3NidF9tZWFuX3RlbXBfc3VydmV5X2ZhY2V0XzFfMjAuanBnIiwgaGVpZ2h0ID0gMTIsIHdpZHRoID05KQoKKHByZWRzX3NidF9tZWFuX3RlbXBfc3VydmV5X2ZhY2V0XzIxXzM0IDwtIGdncGxvdChkYXRhID0gZGlzc2ltaWxhcml0aWVzX3RlbXBfZmlzaGluZ19hcmVhLmphY2NhcmRbc3VydmV5X3VuaXQgJWluJSBhbGxfc3VydmV5c1syMTozNF0gJiB5ZWFyID4gMTk3OV0pICsKICBsYWJzKHggPSAiTWVhbiBib3R0b20gdGVtcGVyYXR1cmUgKMuaQykiLCAgeSA9ICLOsi1kaXZlcnNpdHkiKSArCiAgZ2VvbV9wb2ludChhZXMoeCA9IGFzLm51bWVyaWMoeWVhcmx5X21lYW5fYnlwb2ludF9hdmcpLCB5ID0gYW5udWFsX2Rpc3NpbWlsYXJpdHlfdmFsdWUpLCBhbHBoYSA9IDAuMykgKwogIGdlb21fc21vb3RoKGFlcyh4ID0gYXMubnVtZXJpYyh5ZWFybHlfbWVhbl9ieXBvaW50X2F2ZyksIHkgPSBhbm51YWxfZGlzc2ltaWxhcml0eV92YWx1ZSksIG1ldGhvZCA9ICJsbSIpICsKICBmYWNldF93cmFwKH5TdXJ2ZXlfTmFtZV9TZWFzb24sIHNjYWxlcz0gImZyZWUiLCBuY29sID0gNCkgKwogIHRoZW1lX2NsYXNzaWMoKSkKCmdnc2F2ZShwcmVkc19zYnRfbWVhbl90ZW1wX3N1cnZleV9mYWNldF8yMV8zNCwgcGF0aCA9IGhlcmU6OmhlcmUoImZpZ3VyZXMiKSwgZmlsZW5hbWUgPSAicHJlZHNfc2J0X21lYW5fdGVtcF9zdXJ2ZXlfZmFjZXRfMjFfMzQuanBnIiwgaGVpZ2h0ID0gMTIsIHdpZHRoID05KQoKIyMjIyNNSU5JTVVNIFRFTVAKKHByZWRzX3NidF9taW5fdGVtcF9zdXJ2ZXlfZmFjZXRfMV8yMCA8LSBnZ3Bsb3QoZGF0YSA9IGRpc3NpbWlsYXJpdGllc190ZW1wX2Zpc2hpbmdfYXJlYS5qYWNjYXJkW3N1cnZleV91bml0ICVpbiUgYWxsX3N1cnZleXNbMToyMF0gJiB5ZWFyID4gMTk3OV0pICsKICBsYWJzKHggPSAiTWluaW11bSBib3R0b20gdGVtcGVyYXR1cmUgKMuaQykiLCAgeSA9ICLOsi1kaXZlcnNpdHkiKSArCiAgZ2VvbV9wb2ludChhZXMoeCA9IGFzLm51bWVyaWMoeWVhcmx5X21pbl9ieXBvaW50X2F2ZyksIHkgPSBhbm51YWxfZGlzc2ltaWxhcml0eV92YWx1ZSksIGFscGhhID0gMC4zKSArCiAgZ2VvbV9zbW9vdGgoYWVzKHggPSBhcy5udW1lcmljKHllYXJseV9taW5fYnlwb2ludF9hdmcpLCB5ID0gYW5udWFsX2Rpc3NpbWlsYXJpdHlfdmFsdWUpLCBtZXRob2QgPSAibG0iKSArCiAgZmFjZXRfd3JhcCh+U3VydmV5X05hbWVfU2Vhc29uLCBzY2FsZXM9ICJmcmVlIiwgbmNvbCA9IDQpICsKICB0aGVtZV9jbGFzc2ljKCkpCgpnZ3NhdmUocHJlZHNfc2J0X21pbl90ZW1wX3N1cnZleV9mYWNldF8xXzIwLCBwYXRoID0gaGVyZTo6aGVyZSgiZmlndXJlcyIpLCBmaWxlbmFtZSA9ICJwcmVkc19zYnRfbWluX3RlbXBfc3VydmV5X2ZhY2V0XzFfMjAuanBnIiwgaGVpZ2h0ID0gMTIsIHdpZHRoID05KQoKKHByZWRzX3NidF9taW5fdGVtcF9zdXJ2ZXlfZmFjZXRfMjFfMzQgPC0gZ2dwbG90KGRhdGEgPSBkaXNzaW1pbGFyaXRpZXNfdGVtcF9maXNoaW5nX2FyZWEuamFjY2FyZFtzdXJ2ZXlfdW5pdCAlaW4lIGFsbF9zdXJ2ZXlzWzIxOjM0XSAmIHllYXIgPiAxOTc5XSkgKwogIGxhYnMoeCA9ICJNaW5pbXVtIGJvdHRvbSB0ZW1wZXJhdHVyZSAoy5pDKSIsICB5ID0gIs6yLWRpdmVyc2l0eSIpICsKICBnZW9tX3BvaW50KGFlcyh4ID0gYXMubnVtZXJpYyh5ZWFybHlfbWluX2J5cG9pbnRfYXZnKSwgeSA9IGFubnVhbF9kaXNzaW1pbGFyaXR5X3ZhbHVlKSwgYWxwaGEgPSAwLjMpICsKICBnZW9tX3Ntb290aChhZXMoeCA9IGFzLm51bWVyaWMoeWVhcmx5X21pbl9ieXBvaW50X2F2ZyksIHkgPSBhbm51YWxfZGlzc2ltaWxhcml0eV92YWx1ZSksIG1ldGhvZCA9ICJsbSIpICsKICBmYWNldF93cmFwKH5TdXJ2ZXlfTmFtZV9TZWFzb24sIHNjYWxlcz0gImZyZWUiLCBuY29sID0gNCkgKwogIHRoZW1lX2NsYXNzaWMoKSkKCmdnc2F2ZShwcmVkc19zYnRfbWluX3RlbXBfc3VydmV5X2ZhY2V0XzIxXzM0LCBwYXRoID0gaGVyZTo6aGVyZSgiZmlndXJlcyIpLCBmaWxlbmFtZSA9ICJwcmVkc19zYnRfbWluX3RlbXBfc3VydmV5X2ZhY2V0XzIxXzM0LmpwZyIsIGhlaWdodCA9IDEyLCB3aWR0aCA9OSkKCiMjIyMjIyNGSVNISU5HCgpkaXNzaW1pbGFyaXRpZXNfdGVtcF9maXNoaW5nX2FyZWEuamFjY2FyZC5jYyA8LSBkaXNzaW1pbGFyaXRpZXNfdGVtcF9maXNoaW5nX2FyZWEuamFjY2FyZFtjb21wbGV0ZS5jYXNlcyhkaXNzaW1pbGFyaXRpZXNfdGVtcF9maXNoaW5nX2FyZWEuamFjY2FyZFssc3VtbWVkX3Rvbm5lc19zY2FsZWRfYnlyZWddKSxdCgoocHJlZHNfc2J0X21lYW5fZmlzaGluZ19zdXJ2ZXlfZmFjZXRfMV8yMCA8LSBnZ3Bsb3QoZGF0YSA9IGRpc3NpbWlsYXJpdGllc190ZW1wX2Zpc2hpbmdfYXJlYS5qYWNjYXJkLmNjW3N1cnZleV91bml0ICVpbiUgYWxsX3N1cnZleXNbMToyMF0gJiB5ZWFyID4gMTk3OV0pICsKICBsYWJzKHggPSAiUmVsYXRpdmUgZmlzaGluZyBjYXRjaCIsICB5ID0gIs6yLWRpdmVyc2l0eSIpICsKICBnZW9tX3BvaW50KGFlcyh4ID0gc3VtbWVkX3Rvbm5lc19zY2FsZWRfYnlyZWcsIHkgPSBhbm51YWxfZGlzc2ltaWxhcml0eV92YWx1ZSksIGFscGhhID0gMC4zKSArCiAgZ2VvbV9zbW9vdGgoYWVzKHggPSBzdW1tZWRfdG9ubmVzX3NjYWxlZF9ieXJlZywgeSA9IGFubnVhbF9kaXNzaW1pbGFyaXR5X3ZhbHVlKSwgbWV0aG9kID0gImxtIikgKwogIGZhY2V0X3dyYXAoflN1cnZleV9OYW1lX1NlYXNvbiwgc2NhbGVzPSAiZnJlZSIsIG5jb2wgPSA0KSArCiAgdGhlbWVfY2xhc3NpYygpKQoKZ2dzYXZlKHByZWRzX3NidF9tZWFuX2Zpc2hpbmdfc3VydmV5X2ZhY2V0XzFfMjAsIHBhdGggPSBoZXJlOjpoZXJlKCJmaWd1cmVzIiksIGZpbGVuYW1lID0gInByZWRzX3NidF9tZWFuX2Zpc2hpbmdfc3VydmV5X2ZhY2V0XzFfMjAuanBnIiwgaGVpZ2h0ID0gMTIsIHdpZHRoID05KQoKKHByZWRzX3NidF9tZWFuX2Zpc2hpbmdfc3VydmV5X2ZhY2V0XzIxXzM0IDwtIGdncGxvdChkYXRhID0gZGlzc2ltaWxhcml0aWVzX3RlbXBfZmlzaGluZ19hcmVhLmphY2NhcmQuY2Nbc3VydmV5X3VuaXQgJWluJSBhbGxfc3VydmV5c1tjKDIxOjM0KV0gJiB5ZWFyID4gMTk3OV0pICsKICBsYWJzKHggPSAiUmVsYXRpdmUgZmlzaGluZyBjYXRjaCIsICB5ID0gIs6yLWRpdmVyc2l0eSIpICsKICBnZW9tX3BvaW50KGFlcyh4ID0gc3VtbWVkX3Rvbm5lc19zY2FsZWRfYnlyZWcsIHkgPSBhbm51YWxfZGlzc2ltaWxhcml0eV92YWx1ZSksIGFscGhhID0gMC4zKSArCiAgZ2VvbV9zbW9vdGgoYWVzKHggPSBzdW1tZWRfdG9ubmVzX3NjYWxlZF9ieXJlZywgeSA9IGFubnVhbF9kaXNzaW1pbGFyaXR5X3ZhbHVlKSwgbWV0aG9kID0gImxtIikgKwogIGZhY2V0X3dyYXAoflN1cnZleV9OYW1lX1NlYXNvbiwgc2NhbGVzPSAiZnJlZSIsIG5jb2wgPSA0KSArCiAgdGhlbWVfY2xhc3NpYygpKQoKZ2dzYXZlKHByZWRzX3NidF9tZWFuX2Zpc2hpbmdfc3VydmV5X2ZhY2V0XzIxXzM0LCBwYXRoID0gaGVyZTo6aGVyZSgiZmlndXJlcyIpLCBmaWxlbmFtZSA9ICJwcmVkc19zYnRfbWVhbl9maXNoaW5nX3N1cnZleV9mYWNldF8yMV8zNC5qcGciLCBoZWlnaHQgPSAxMiwgd2lkdGggPTkpCgoKYGBgCgojIyNQbG90IG51bWJlciBvZiB0b3dzIHBlciB5ZWFyIHBlciByZWdpb24KYGBge3J9CnRvd3NfeWVhciA8LSB1bmlxdWUoZGlzc2ltaWxhcml0aWVzX3RlbXBfZmlzaGluZ19hcmVhLmphY2NhcmRbLC4oc3VydmV5X3VuaXQsIGhhdWxfaWRfY291bnRfYW5udWFsLCBhcmVhX2ttLCB5ZWFyLCBTdXJ2ZXlfTmFtZV9TZWFzb24pXSkKCm1pbl9oYXVsX2RlbnNpdHkgPC0gbWluKHRvd3NfeWVhciRoYXVsX2lkX2NvdW50X2FubnVhbC90b3dzX3llYXIkYXJlYV9rbSkKbWF4X2hhdWxfZGVuc2l0eSA8LSBtYXgodG93c195ZWFyJGhhdWxfaWRfY291bnRfYW5udWFsL3Rvd3NfeWVhciRhcmVhX2ttKQoKKHRvd19kZW5zaXR5X3N1cnZleV9mYWNldF8xXzIwIDwtIGdncGxvdChkYXRhID0gdG93c195ZWFyW3N1cnZleV91bml0ICVpbiUgYWxsX3N1cnZleXNbMToyMF1dKSArCiAgbGFicyh4ID0gIlllYXIiLCAgeSA9IGV4cHJlc3Npb24oIlRvdyBkZW5zaXR5ICh0b3dzIHBlciBrbSJeMioiKSIpKSArCiAgZ2VvbV9wb2ludChhZXMoeCA9IHllYXIsIHkgPSBoYXVsX2lkX2NvdW50X2FubnVhbC9hcmVhX2ttKSkgKwogIHlsaW0oYyhtaW5faGF1bF9kZW5zaXR5LTAuMDAwMSwgbWF4X2hhdWxfZGVuc2l0eSswLjAwMDEpKSArCiAgZmFjZXRfd3JhcCh+U3VydmV5X05hbWVfU2Vhc29uLCBuY29sID0gNCkgKwogIHRoZW1lX2NsYXNzaWMoKSkKCmdnc2F2ZSh0b3dfZGVuc2l0eV9zdXJ2ZXlfZmFjZXRfMV8yMCwgcGF0aCA9IGhlcmU6OmhlcmUoImZpZ3VyZXMiKSwgZmlsZW5hbWUgPSAidG93X2RlbnNpdHlfc3VydmV5X2ZhY2V0XzFfMjAuanBnIiwgaGVpZ2h0ID0gMTIsIHdpZHRoID05KQoKKHRvd19kZW5zaXR5X3N1cnZleV9mYWNldF8yMV8zNCA8LSBnZ3Bsb3QoZGF0YSA9IHRvd3NfeWVhcltzdXJ2ZXlfdW5pdCAlaW4lIGFsbF9zdXJ2ZXlzWzIxOjM0XV0pICsKICBsYWJzKHggPSAiWWVhciIsICB5ID0gZXhwcmVzc2lvbigiVG93IGRlbnNpdHkgKHRvd3MgcGVyIGttIl4yKiIpIikpICsKICBnZW9tX3BvaW50KGFlcyh4ID0geWVhciwgeSA9IGhhdWxfaWRfY291bnRfYW5udWFsL2FyZWFfa20pKSArCiAgeWxpbShjKG1pbl9oYXVsX2RlbnNpdHktMC4wMDAxLCBtYXhfaGF1bF9kZW5zaXR5KzAuMDAwMSkpICsKICBmYWNldF93cmFwKH5TdXJ2ZXlfTmFtZV9TZWFzb24sIG5jb2wgPSA0KSArCiAgdGhlbWVfY2xhc3NpYygpKQoKZ2dzYXZlKHRvd19kZW5zaXR5X3N1cnZleV9mYWNldF8yMV8zNCwgcGF0aCA9IGhlcmU6OmhlcmUoImZpZ3VyZXMiKSwgZmlsZW5hbWUgPSAidG93X2RlbnNpdHlfc3VydmV5X2ZhY2V0XzIxXzM0LmpwZyIsIGhlaWdodCA9IDEyLCB3aWR0aCA9OSkKCiNtaW5pbXVtIGFuZCBtYXhpbXVtIGRpc3NpbWlsYXJpdHkgdmFsdWUKbWluX2Rpc3NpbWlsYXJpdHkgPC0gbWluKGRpc3NpbWlsYXJpdGllc190ZW1wX2Zpc2hpbmdfYXJlYS5qYWNjYXJkJGFubnVhbF9kaXNzaW1pbGFyaXR5X3ZhbHVlKQptYXhfZGlzc2ltaWxhcml0eSA8LSBtYXgoZGlzc2ltaWxhcml0aWVzX3RlbXBfZmlzaGluZ19hcmVhLmphY2NhcmQkYW5udWFsX2Rpc3NpbWlsYXJpdHlfdmFsdWUpCgojaG93IGRvZXMgdG93IGRlbnNpdHkgdmFyeSB3aXRoIGRpc3NpbWlsYXJpdHk/CnRvd19kZW5zaXR5X2Rpc3NpbWlsYXJpdHlfMV8yMCA8LSAKICBnZ3Bsb3QoZGF0YSA9IGRpc3NpbWlsYXJpdGllc190ZW1wX2Zpc2hpbmdfYXJlYS5qYWNjYXJkW2Rpc3NpbWlsYXJpdHlfbWV0cmljID09ICJqYWNjYXJkX2Rpc3NpbWlsYXJpdHlfdG90YWwiICYgc3VydmV5X3VuaXQgJWluJSBhbGxfc3VydmV5c1sxOjIwXV0pICsKICBnZW9tX3BvaW50KGFlcyh4ID0gKGhhdWxfaWRfY291bnRfYW5udWFsL2FyZWFfa20pLCB5ID0gYW5udWFsX2Rpc3NpbWlsYXJpdHlfdmFsdWUsIGNvbG9yID0geWVhciksIHNpemUgPSAyKSArCiAgdmlyaWRpczo6c2NhbGVfY29sb3JfdmlyaWRpcygpICsKICBmYWNldF93cmFwKH5TdXJ2ZXlfTmFtZV9TZWFzb24sIG5jb2wgPSA0KSArCiAgbGFicyh4ID0gZXhwcmVzc2lvbigiVG93IGRlbnNpdHkgKHRvd3MgcGVyIGttIl4yKiIpIiksIHkgPSAizrItZGl2ZXJzaXR5IiwgY29sb3IgPSAiWWVhciIpICsKICAgIHhsaW0oYyhtaW5faGF1bF9kZW5zaXR5LTAuMDAwMSwgbWF4X2hhdWxfZGVuc2l0eSswLjAwMDEpKSArCiAgICB5bGltKGMobWluX2Rpc3NpbWlsYXJpdHktMC4wMSxtYXhfZGlzc2ltaWxhcml0eSswLjAxKSkgKwogIHRoZW1lX2NsYXNzaWMoKQoKZ2dzYXZlKHRvd19kZW5zaXR5X2Rpc3NpbWlsYXJpdHlfMV8yMCwgcGF0aCA9IGhlcmU6OmhlcmUoImZpZ3VyZXMiKSwgZmlsZW5hbWUgPSAidG93X2RlbnNpdHlfZGlzc2ltaWxhcml0eV8xXzIwLmpwZyIsIGhlaWdodCA9IDEyLCB3aWR0aCA9OSkKCnRvd19kZW5zaXR5X2Rpc3NpbWlsYXJpdHlfMjFfMzQgPC0gCiAgZ2dwbG90KGRhdGEgPSBkaXNzaW1pbGFyaXRpZXNfdGVtcF9maXNoaW5nX2FyZWEuamFjY2FyZFtkaXNzaW1pbGFyaXR5X21ldHJpYyA9PSAiamFjY2FyZF9kaXNzaW1pbGFyaXR5X3RvdGFsIiAmIHN1cnZleV91bml0ICVpbiUgYWxsX3N1cnZleXNbMjE6MzRdXSkgKwogIGdlb21fcG9pbnQoYWVzKHggPSAoaGF1bF9pZF9jb3VudF9hbm51YWwvYXJlYV9rbSksIHkgPSBhbm51YWxfZGlzc2ltaWxhcml0eV92YWx1ZSwgY29sb3IgPSB5ZWFyKSwgc2l6ZSA9IDIpICsKICB2aXJpZGlzOjpzY2FsZV9jb2xvcl92aXJpZGlzKCkgKwogIGZhY2V0X3dyYXAoflN1cnZleV9OYW1lX1NlYXNvbiwgbmNvbCA9IDQpICsKICBsYWJzKHggPSBleHByZXNzaW9uKCJUb3cgZGVuc2l0eSAodG93cyBwZXIga20iXjIqIikiKSwgeSA9ICLOsi1kaXZlcnNpdHkiLCBjb2xvciA9ICJZZWFyIikgKwogICAgeGxpbShjKG1pbl9oYXVsX2RlbnNpdHktMC4wMDAxLCBtYXhfaGF1bF9kZW5zaXR5KzAuMDAwMSkpICsKICAgIHlsaW0oYyhtaW5fZGlzc2ltaWxhcml0eS0wLjAxLG1heF9kaXNzaW1pbGFyaXR5KzAuMDEpKSArCiAgdGhlbWVfY2xhc3NpYygpCgpnZ3NhdmUodG93X2RlbnNpdHlfZGlzc2ltaWxhcml0eV8yMV8zNCwgcGF0aCA9IGhlcmU6OmhlcmUoImZpZ3VyZXMiKSwgZmlsZW5hbWUgPSAidG93X2RlbnNpdHlfZGlzc2ltaWxhcml0eV8yMV8zNC5qcGciLCBoZWlnaHQgPSAxMiwgd2lkdGggPTkpCmBgYAoKCiMjI1NldCB1cCBkcmVkZ2UgdG8gaWRlbnRpZnkgYmVzdCBwZXJmb3JtaW5nIG1vZGVscwpgYGB7cn0KCm9wdGlvbnMobmEuYWN0aW9uID0gIm5hLmZhaWwiKQoKZGlzc2ltaWxhcml0eV9jb3ZhcmlhdGVzX2RyZWRnZS5kdCA8LSBkaXNzaW1pbGFyaXRpZXNfdGVtcF9maXNoaW5nX2FyZWEuamFjY2FyZFssLgogICAgICAgICAgICAgICAgICAoeWVhciwgc3VydmV5X3VuaXQsCiAgICAgICAgICAgICAgICAgICAgeWVhcmx5X21lYW5fYnlwb2ludF9hdmcsIHllYXJseV9tYXhfYnlwb2ludF9hdmcsIHllYXJseV9taW5fYnlwb2ludF9hdmcseWVhcmx5X3NlYXNfYnlwb2ludF9hdmcsCiAgICAgICAgICAgICAgICAgICAgeWVhcmx5X21lYW5fYnlwb2ludF9TRCwgeWVhcmx5X21heF9ieXBvaW50X1NELCB5ZWFybHlfbWluX2J5cG9pbnRfU0QseWVhcmx5X3NlYXNfYnlwb2ludF9TRCwKICAgICAgICAgICAgICAgICAgICB5ZWFybHlfbWVhbl9ieXBvaW50X2F2Zy5zLCB5ZWFybHlfbWF4X2J5cG9pbnRfYXZnLnMsIHllYXJseV9taW5fYnlwb2ludF9hdmcucyx5ZWFybHlfc2Vhc19ieXBvaW50X2F2Zy5zLAogICAgICAgICAgICAgICAgICAgIGFubnVhbF9kaXNzaW1pbGFyaXR5X3ZhbHVlLAogICAgICAgICAgICAgICAgICAgIGhhdWxfaWRfY291bnRfYW5udWFsLAogICAgICAgICAgICAgICAgICAgIHNwcF9jb3VudF9hbm51YWwsIGRlcHRoX2FubnVhbF9hdmcsCiAgICAgICAgICAgICAgICAgICAgZGVwdGhfYW5udWFsX3JhbmdlLCBsYXRpdHVkZV9hbm51YWxfYXZnLAogICAgICAgICAgICAgICAgICAgIGxhdGl0dWRlX2FubnVhbF9yYW5nZSwgYXJlYV9rbSwgYXZnX2p1bGlhbl9hbm51YWwsIHN1bW1lZF90b25uZXNfc2NhbGVkX2J5cmVnKV0KCiNtZXJnZSBpbiB3aXRoIGNvbG9ycyBmb3IgcGxvdHRpbmcgcHJlZGljdGlvbnMgYnkgc3VydmV5CmRpc3NpbWlsYXJpdHlfY292YXJpYXRlc19kcmVkZ2UuZHQgPC0gY29sb3JfbGlua1tkaXNzaW1pbGFyaXR5X2NvdmFyaWF0ZXNfZHJlZGdlLmR0LCBvbiA9ICJzdXJ2ZXlfdW5pdCJdCgojSWYgTkEgZm9yIGFueSBjb3ZhcmlhdGUsIGRlbGV0ZSByb3cKVmlldyhkaXNzaW1pbGFyaXR5X2NvdmFyaWF0ZXNfZHJlZGdlLmR0KQojRGVsZXRlZDoKICAjQmVmb3JlIDE5ODAgYW5kIGFmdGVyIDIwMTkKICAjR3VsZiBvZiBTYWludCBMYXVyZW5jZSBTb3V0aCAobm8gZGVwdGggZGF0YSkKICAjTm8gY2xlYXIgU0FVIG1hdGNoIGZvciBSb2NrYWxsIFBsYXRlYXUKZGlzc2ltaWxhcml0eV9jb3ZhcmlhdGVzX2RyZWRnZS5kdCA8LSBkaXNzaW1pbGFyaXR5X2NvdmFyaWF0ZXNfZHJlZGdlLmR0W2NvbXBsZXRlLmNhc2VzKGRpc3NpbWlsYXJpdHlfY292YXJpYXRlc19kcmVkZ2UuZHQpXQoKCmRpc3NpbWlsYXJpdHlfY292YXJpYXRlc19kcmVkZ2UuZHRbLCB5ZWFybHlfbWVhbl9ieXBvaW50X2F2Zy5zY2FsZWRhY3Jvc3NhbGwgOj0gc2NhbGUoeWVhcmx5X21lYW5fYnlwb2ludF9hdmcpXVssIHllYXJseV9tZWFuX2J5cG9pbnRfU0Quc2NhbGVkYWNyb3NzYWxsIDo9IHNjYWxlKHllYXJseV9tZWFuX2J5cG9pbnRfU0QpXVssIHllYXJseV9taW5fYnlwb2ludF9hdmcuc2NhbGVkYWNyb3NzYWxsIDo9IHNjYWxlKHllYXJseV9taW5fYnlwb2ludF9hdmcpXVssIHllYXJseV9tYXhfYnlwb2ludF9hdmcuc2NhbGVkYWNyb3NzYWxsIDo9IHNjYWxlKHllYXJseV9tYXhfYnlwb2ludF9hdmcpXVssIHllYXJseV9zZWFzX2J5cG9pbnRfYXZnLnNjYWxlZGFjcm9zc2FsbCA6PSBzY2FsZSh5ZWFybHlfc2Vhc19ieXBvaW50X2F2ZyldWyxoYXVsX2lkX2NvdW50X2FubnVhbC5zY2FsZWRhY3Jvc3NhbGwgOj0gc2NhbGUoaGF1bF9pZF9jb3VudF9hbm51YWwpXVssc3BwX2NvdW50X2FubnVhbC5zY2FsZWRhY3Jvc3NhbGwgOj0gc2NhbGUoc3BwX2NvdW50X2FubnVhbCldWyxkZXB0aF9hbm51YWxfYXZnLnNjYWxlZGFjcm9zc2FsbCA6PSBzY2FsZShkZXB0aF9hbm51YWxfYXZnKV1bLGRlcHRoX2FubnVhbF9yYW5nZS5zY2FsZWRhY3Jvc3NhbGwgOj0gc2NhbGUoZGVwdGhfYW5udWFsX3JhbmdlKV0gWyxsYXRpdHVkZV9hbm51YWxfYXZnLnNjYWxlZGFjcm9zc2FsbCA6PSBzY2FsZShsYXRpdHVkZV9hbm51YWxfYXZnKV1bLGxhdGl0dWRlX2FubnVhbF9yYW5nZS5zY2FsZWRhY3Jvc3NhbGwgOj0gc2NhbGUobGF0aXR1ZGVfYW5udWFsX3JhbmdlKV1bLGFyZWFfa20uc2NhbGVkYWNyb3NzYWxsIDo9IHNjYWxlKGFyZWFfa20pXVssanVsaWFuX3NjYWxlZCA6PSBzY2FsZShhdmdfanVsaWFuX2FubnVhbCldCgoKYGBgCgojIyNGdWxsIG1vZGVsCn4gdGVtcCArIHN1cnZleV91bml0ICsgZmlzaGluZyArIGFyZWEgKyBsYXRpdHVkZSByYW5nZSArIGxhdGl0dWRlIGF2ZXJhZ2UgKyBkZXB0aCByYW5nZSArIGRlcHRoIGF2ZXJhZ2UgKyBzcHAgY291bnQgKyAjIG9mIGhhdWxzICsganVsaWFuIGRheSArIEFSIGZvciB5ZWFyCgpGb3IgdGVtcGVyYXR1cmUsIHdlIHdpbGwgbG9vayBhdDoKLW1lYW4gKHNjYWxlZCBhY3Jvc3MgYWxsIHJlZ2lvbnMpCi1tYXggIChzY2FsZWQgYWNyb3NzIGFsbCByZWdpb25zKQotbWluIChzY2FsZWQgYWNyb3NzIGFsbCByZWdpb25zKQotc2VhcyAgKHNjYWxlZCBhY3Jvc3MgYWxsIHJlZ2lvbnMpCi1TRAoKQ29tcGFyaW5nIHRlbXAgdmFyaWFibGVzIEFORCB0aGUgcHJlc2VuY2UvYWJzZW5jZSBvZiBhIHRlbXBvcmFsIGF1dG9jb3JyZWxhdGlvbiB0ZXJtCmBgYHtyIGZpdCBnbG9iYWwgbW9kfQoKZ2xvYmFsX21vZF9tZWFuX3RlbXBfZ2xzIDwtIGdscyhhbm51YWxfZGlzc2ltaWxhcml0eV92YWx1ZSB+IAogICAgICAgICAgICAgICAgICAgICAgICAgICAgIHN1cnZleV91bml0KnllYXJseV9tZWFuX2J5cG9pbnRfYXZnLnNjYWxlZGFjcm9zc2FsbCArICN0ZW1wIGFuZCBzdXJ2ZXkgdW5pdCAocG9zc2libGUgaW50ZXJhY3Rpb24pCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc3VydmV5X3VuaXQqc3VtbWVkX3Rvbm5lc19zY2FsZWRfYnlyZWcgKyAjZmlzaGluZyBlZmZvcnQgYW5kIHN1cnZleSB1bml0IChwb3NzaWJsZSBpbnRlcmFjdGlvbikKICAgICAgICAgICAgICAgICAgICAgICAgICAgICBhcmVhX2ttLnNjYWxlZGFjcm9zc2FsbCArICNhcmVhCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbGF0aXR1ZGVfYW5udWFsX3JhbmdlLnNjYWxlZGFjcm9zc2FsbCArICNsYXRpdHVkZSByYW5nZQogICAgICAgICAgICAgICAgICAgICAgICAgICAgIGxhdGl0dWRlX2FubnVhbF9hdmcuc2NhbGVkYWNyb3NzYWxsICsgI2xhdGl0dWRlIGF2ZwogICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRlcHRoX2FubnVhbF9yYW5nZS5zY2FsZWRhY3Jvc3NhbGwgKyAjZGVwdGggcmFuZ2UKICAgICAgICAgICAgICAgICAgICAgICAgICAgICBkZXB0aF9hbm51YWxfYXZnLnNjYWxlZGFjcm9zc2FsbCArICNkZXB0aCBhdmcKICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzcHBfY291bnRfYW5udWFsLnNjYWxlZGFjcm9zc2FsbCArICNzcHAgIwogICAgICAgICAgICAgICAgICAgICAgICAgICAgIGhhdWxfaWRfY291bnRfYW5udWFsLnNjYWxlZGFjcm9zc2FsbCArCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAganVsaWFuX3NjYWxlZCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgY29ycmVsYXRpb24gPSBjb3JBUjEoZm9ybT1+eWVhciB8IHN1cnZleV91bml0KSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICBkYXRhID0gZGlzc2ltaWxhcml0eV9jb3ZhcmlhdGVzX2RyZWRnZS5kdCkKCmdsb2JhbF9tb2RfbWVhbl90ZW1wX2xtIDwtIGxtKGFubnVhbF9kaXNzaW1pbGFyaXR5X3ZhbHVlIH4gCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc3VydmV5X3VuaXQqeWVhcmx5X21lYW5fYnlwb2ludF9hdmcuc2NhbGVkYWNyb3NzYWxsICsgI3RlbXAgYW5kIHN1cnZleSB1bml0IChwb3NzaWJsZSBpbnRlcmFjdGlvbikKICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzdXJ2ZXlfdW5pdCpzdW1tZWRfdG9ubmVzX3NjYWxlZF9ieXJlZyArICNmaXNoaW5nIGVmZm9ydCBhbmQgc3VydmV5IHVuaXQgKHBvc3NpYmxlIGludGVyYWN0aW9uKQogICAgICAgICAgICAgICAgICAgICAgICAgICAgIGFyZWFfa20uc2NhbGVkYWNyb3NzYWxsICsgI2FyZWEKICAgICAgICAgICAgICAgICAgICAgICAgICAgICBsYXRpdHVkZV9hbm51YWxfcmFuZ2Uuc2NhbGVkYWNyb3NzYWxsICsgI2xhdGl0dWRlIHJhbmdlCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbGF0aXR1ZGVfYW5udWFsX2F2Zy5zY2FsZWRhY3Jvc3NhbGwgKyAjbGF0aXR1ZGUgYXZnCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZGVwdGhfYW5udWFsX3JhbmdlLnNjYWxlZGFjcm9zc2FsbCArICNkZXB0aCByYW5nZQogICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRlcHRoX2FubnVhbF9hdmcuc2NhbGVkYWNyb3NzYWxsICsgI2RlcHRoIGF2ZwogICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNwcF9jb3VudF9hbm51YWwuc2NhbGVkYWNyb3NzYWxsICsgI3NwcCAjCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaGF1bF9pZF9jb3VudF9hbm51YWwuc2NhbGVkYWNyb3NzYWxsICsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICBqdWxpYW5fc2NhbGVkLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRhdGEgPSBkaXNzaW1pbGFyaXR5X2NvdmFyaWF0ZXNfZHJlZGdlLmR0KQoKZ2xvYmFsX21vZF9tYXhfdGVtcF9sbSA8LSBsbShhbm51YWxfZGlzc2ltaWxhcml0eV92YWx1ZSB+IAogICAgICAgICAgICAgICAgICAgICAgICAgICAgIHN1cnZleV91bml0KnllYXJseV9tYXhfYnlwb2ludF9hdmcuc2NhbGVkYWNyb3NzYWxsICsgI3RlbXAgYW5kIHN1cnZleSB1bml0IChwb3NzaWJsZSBpbnRlcmFjdGlvbikKICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzdXJ2ZXlfdW5pdCpzdW1tZWRfdG9ubmVzX3NjYWxlZF9ieXJlZyArICNmaXNoaW5nIGVmZm9ydCBhbmQgc3VydmV5IHVuaXQgKHBvc3NpYmxlIGludGVyYWN0aW9uKQogICAgICAgICAgICAgICAgICAgICAgICAgICAgIGFyZWFfa20uc2NhbGVkYWNyb3NzYWxsICsgI2FyZWEKICAgICAgICAgICAgICAgICAgICAgICAgICAgICBsYXRpdHVkZV9hbm51YWxfcmFuZ2Uuc2NhbGVkYWNyb3NzYWxsICsgI2xhdGl0dWRlIHJhbmdlCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbGF0aXR1ZGVfYW5udWFsX2F2Zy5zY2FsZWRhY3Jvc3NhbGwgKyAjbGF0aXR1ZGUgYXZnCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZGVwdGhfYW5udWFsX3JhbmdlLnNjYWxlZGFjcm9zc2FsbCArICNkZXB0aCByYW5nZQogICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRlcHRoX2FubnVhbF9hdmcuc2NhbGVkYWNyb3NzYWxsICsgI2RlcHRoIGF2ZwogICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNwcF9jb3VudF9hbm51YWwuc2NhbGVkYWNyb3NzYWxsICsgI3NwcCAjCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaGF1bF9pZF9jb3VudF9hbm51YWwuc2NhbGVkYWNyb3NzYWxsICsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGp1bGlhbl9zY2FsZWQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZGF0YSA9IGRpc3NpbWlsYXJpdHlfY292YXJpYXRlc19kcmVkZ2UuZHQpCgpnbG9iYWxfbW9kX21heF90ZW1wX2dscyA8LWdscyhhbm51YWxfZGlzc2ltaWxhcml0eV92YWx1ZSB+IAogICAgICAgICAgICAgICAgICAgICAgICAgICAgIHN1cnZleV91bml0KnllYXJseV9tYXhfYnlwb2ludF9hdmcuc2NhbGVkYWNyb3NzYWxsICsgI3RlbXAgYW5kIHN1cnZleSB1bml0IChwb3NzaWJsZSBpbnRlcmFjdGlvbikKICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzdXJ2ZXlfdW5pdCpzdW1tZWRfdG9ubmVzX3NjYWxlZF9ieXJlZyArICNmaXNoaW5nIGVmZm9ydCBhbmQgc3VydmV5IHVuaXQgKHBvc3NpYmxlIGludGVyYWN0aW9uKQogICAgICAgICAgICAgICAgICAgICAgICAgICAgIGFyZWFfa20uc2NhbGVkYWNyb3NzYWxsICsgI2FyZWEKICAgICAgICAgICAgICAgICAgICAgICAgICAgICBsYXRpdHVkZV9hbm51YWxfcmFuZ2Uuc2NhbGVkYWNyb3NzYWxsICsgI2xhdGl0dWRlIHJhbmdlCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbGF0aXR1ZGVfYW5udWFsX2F2Zy5zY2FsZWRhY3Jvc3NhbGwgKyAjbGF0aXR1ZGUgYXZnCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZGVwdGhfYW5udWFsX3JhbmdlLnNjYWxlZGFjcm9zc2FsbCArICNkZXB0aCByYW5nZQogICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRlcHRoX2FubnVhbF9hdmcuc2NhbGVkYWNyb3NzYWxsICsgI2RlcHRoIGF2ZwogICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNwcF9jb3VudF9hbm51YWwuc2NhbGVkYWNyb3NzYWxsICsgI3NwcCAjCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaGF1bF9pZF9jb3VudF9hbm51YWwuc2NhbGVkYWNyb3NzYWxsICsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGp1bGlhbl9zY2FsZWQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb3JyZWxhdGlvbiA9IGNvckFSMShmb3JtPX55ZWFyIHwgc3VydmV5X3VuaXQpLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRhdGEgPSBkaXNzaW1pbGFyaXR5X2NvdmFyaWF0ZXNfZHJlZGdlLmR0KQoKZ2xvYmFsX21vZF9taW5fdGVtcF9sbSA8LSBsbShhbm51YWxfZGlzc2ltaWxhcml0eV92YWx1ZSB+IAogICAgICAgICAgICAgICAgICAgICAgICAgICAgIHN1cnZleV91bml0KnllYXJseV9taW5fYnlwb2ludF9hdmcuc2NhbGVkYWNyb3NzYWxsICsgI3RlbXAgYW5kIHN1cnZleSB1bml0IChwb3NzaWJsZSBpbnRlcmFjdGlvbikKICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzdXJ2ZXlfdW5pdCpzdW1tZWRfdG9ubmVzX3NjYWxlZF9ieXJlZyArICNmaXNoaW5nIGVmZm9ydCBhbmQgc3VydmV5IHVuaXQgKHBvc3NpYmxlIGludGVyYWN0aW9uKQogICAgICAgICAgICAgICAgICAgICAgICAgICAgIGFyZWFfa20uc2NhbGVkYWNyb3NzYWxsICsgI2FyZWEKICAgICAgICAgICAgICAgICAgICAgICAgICAgICBsYXRpdHVkZV9hbm51YWxfcmFuZ2Uuc2NhbGVkYWNyb3NzYWxsICsgI2xhdGl0dWRlIHJhbmdlCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbGF0aXR1ZGVfYW5udWFsX2F2Zy5zY2FsZWRhY3Jvc3NhbGwgKyAjbGF0aXR1ZGUgYXZnCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZGVwdGhfYW5udWFsX3JhbmdlLnNjYWxlZGFjcm9zc2FsbCArICNkZXB0aCByYW5nZQogICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRlcHRoX2FubnVhbF9hdmcuc2NhbGVkYWNyb3NzYWxsICsgI2RlcHRoIGF2ZwogICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNwcF9jb3VudF9hbm51YWwuc2NhbGVkYWNyb3NzYWxsICsgI3NwcCAjCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaGF1bF9pZF9jb3VudF9hbm51YWwuc2NhbGVkYWNyb3NzYWxsICsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGp1bGlhbl9zY2FsZWQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZGF0YSA9IGRpc3NpbWlsYXJpdHlfY292YXJpYXRlc19kcmVkZ2UuZHQpCgpnbG9iYWxfbW9kX21pbl90ZW1wX2dscyA8LWdscyhhbm51YWxfZGlzc2ltaWxhcml0eV92YWx1ZSB+IAogICAgICAgICAgICAgICAgICAgICAgICAgICAgIHN1cnZleV91bml0KnllYXJseV9taW5fYnlwb2ludF9hdmcuc2NhbGVkYWNyb3NzYWxsICsgI3RlbXAgYW5kIHN1cnZleSB1bml0IChwb3NzaWJsZSBpbnRlcmFjdGlvbikKICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzdXJ2ZXlfdW5pdCpzdW1tZWRfdG9ubmVzX3NjYWxlZF9ieXJlZyArICNmaXNoaW5nIGVmZm9ydCBhbmQgc3VydmV5IHVuaXQgKHBvc3NpYmxlIGludGVyYWN0aW9uKQogICAgICAgICAgICAgICAgICAgICAgICAgICAgIGFyZWFfa20uc2NhbGVkYWNyb3NzYWxsICsgI2FyZWEKICAgICAgICAgICAgICAgICAgICAgICAgICAgICBsYXRpdHVkZV9hbm51YWxfcmFuZ2Uuc2NhbGVkYWNyb3NzYWxsICsgI2xhdGl0dWRlIHJhbmdlCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbGF0aXR1ZGVfYW5udWFsX2F2Zy5zY2FsZWRhY3Jvc3NhbGwgKyAjbGF0aXR1ZGUgYXZnCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZGVwdGhfYW5udWFsX3JhbmdlLnNjYWxlZGFjcm9zc2FsbCArICNkZXB0aCByYW5nZQogICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRlcHRoX2FubnVhbF9hdmcuc2NhbGVkYWNyb3NzYWxsICsgI2RlcHRoIGF2ZwogICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNwcF9jb3VudF9hbm51YWwuc2NhbGVkYWNyb3NzYWxsICsgI3NwcCAjCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaGF1bF9pZF9jb3VudF9hbm51YWwuc2NhbGVkYWNyb3NzYWxsICsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGp1bGlhbl9zY2FsZWQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb3JyZWxhdGlvbiA9IGNvckFSMShmb3JtPX55ZWFyIHwgc3VydmV5X3VuaXQpLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRhdGEgPSBkaXNzaW1pbGFyaXR5X2NvdmFyaWF0ZXNfZHJlZGdlLmR0KQoKZ2xvYmFsX21vZF9zZWFzX3RlbXBfbG0gPC0gbG0oYW5udWFsX2Rpc3NpbWlsYXJpdHlfdmFsdWUgfiAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzdXJ2ZXlfdW5pdCp5ZWFybHlfc2Vhc19ieXBvaW50X2F2Zy5zY2FsZWRhY3Jvc3NhbGwgKyAjdGVtcCBhbmQgc3VydmV5IHVuaXQgKHBvc3NpYmxlIGludGVyYWN0aW9uKQogICAgICAgICAgICAgICAgICAgICAgICAgICAgIHN1cnZleV91bml0KnN1bW1lZF90b25uZXNfc2NhbGVkX2J5cmVnICsgI2Zpc2hpbmcgZWZmb3J0IGFuZCBzdXJ2ZXkgdW5pdCAocG9zc2libGUgaW50ZXJhY3Rpb24pCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYXJlYV9rbS5zY2FsZWRhY3Jvc3NhbGwgKyAjYXJlYQogICAgICAgICAgICAgICAgICAgICAgICAgICAgIGxhdGl0dWRlX2FubnVhbF9yYW5nZS5zY2FsZWRhY3Jvc3NhbGwgKyAjbGF0aXR1ZGUgcmFuZ2UKICAgICAgICAgICAgICAgICAgICAgICAgICAgICBsYXRpdHVkZV9hbm51YWxfYXZnLnNjYWxlZGFjcm9zc2FsbCArICNsYXRpdHVkZSBhdmcKICAgICAgICAgICAgICAgICAgICAgICAgICAgICBkZXB0aF9hbm51YWxfcmFuZ2Uuc2NhbGVkYWNyb3NzYWxsICsgI2RlcHRoIHJhbmdlCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZGVwdGhfYW5udWFsX2F2Zy5zY2FsZWRhY3Jvc3NhbGwgKyAjZGVwdGggYXZnCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc3BwX2NvdW50X2FubnVhbC5zY2FsZWRhY3Jvc3NhbGwgKyAjc3BwICMKICAgICAgICAgICAgICAgICAgICAgICAgICAgICBoYXVsX2lkX2NvdW50X2FubnVhbC5zY2FsZWRhY3Jvc3NhbGwgKwogICAgICAgICAgICAgICAgICAgICAgICAgICAgIGp1bGlhbl9zY2FsZWQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZGF0YSA9IGRpc3NpbWlsYXJpdHlfY292YXJpYXRlc19kcmVkZ2UuZHQpCgpnbG9iYWxfbW9kX3NlYXNfdGVtcF9nbHMgPC0gZ2xzKGFubnVhbF9kaXNzaW1pbGFyaXR5X3ZhbHVlIH4gCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc3VydmV5X3VuaXQqeWVhcmx5X3NlYXNfYnlwb2ludF9hdmcuc2NhbGVkYWNyb3NzYWxsICsgI3RlbXAgYW5kIHN1cnZleSB1bml0IChwb3NzaWJsZSBpbnRlcmFjdGlvbikKICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzdXJ2ZXlfdW5pdCpzdW1tZWRfdG9ubmVzX3NjYWxlZF9ieXJlZyArICNmaXNoaW5nIGVmZm9ydCBhbmQgc3VydmV5IHVuaXQgKHBvc3NpYmxlIGludGVyYWN0aW9uKQogICAgICAgICAgICAgICAgICAgICAgICAgICAgIGFyZWFfa20uc2NhbGVkYWNyb3NzYWxsICsgI2FyZWEKICAgICAgICAgICAgICAgICAgICAgICAgICAgICBsYXRpdHVkZV9hbm51YWxfcmFuZ2Uuc2NhbGVkYWNyb3NzYWxsICsgI2xhdGl0dWRlIHJhbmdlCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbGF0aXR1ZGVfYW5udWFsX2F2Zy5zY2FsZWRhY3Jvc3NhbGwgKyAjbGF0aXR1ZGUgYXZnCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZGVwdGhfYW5udWFsX3JhbmdlLnNjYWxlZGFjcm9zc2FsbCArICNkZXB0aCByYW5nZQogICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRlcHRoX2FubnVhbF9hdmcuc2NhbGVkYWNyb3NzYWxsICsgI2RlcHRoIGF2ZwogICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNwcF9jb3VudF9hbm51YWwuc2NhbGVkYWNyb3NzYWxsICsgI3NwcCAjCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaGF1bF9pZF9jb3VudF9hbm51YWwuc2NhbGVkYWNyb3NzYWxsICsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICBqdWxpYW5fc2NhbGVkLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvcnJlbGF0aW9uID0gY29yQVIxKGZvcm09fnllYXIgfCBzdXJ2ZXlfdW5pdCksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZGF0YSA9IGRpc3NpbWlsYXJpdHlfY292YXJpYXRlc19kcmVkZ2UuZHQpCgpnbG9iYWxfbW9kX1NEX3RlbXBfbG0gPC0gbG0oYW5udWFsX2Rpc3NpbWlsYXJpdHlfdmFsdWUgfiAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzdXJ2ZXlfdW5pdCp5ZWFybHlfbWVhbl9ieXBvaW50X1NELnNjYWxlZGFjcm9zc2FsbCArICN0ZW1wIGFuZCBzdXJ2ZXkgdW5pdCAocG9zc2libGUgaW50ZXJhY3Rpb24pCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc3VydmV5X3VuaXQqc3VtbWVkX3Rvbm5lc19zY2FsZWRfYnlyZWcgKyAjZmlzaGluZyBlZmZvcnQgYW5kIHN1cnZleSB1bml0IChwb3NzaWJsZSBpbnRlcmFjdGlvbikKICAgICAgICAgICAgICAgICAgICAgICAgICAgICBhcmVhX2ttLnNjYWxlZGFjcm9zc2FsbCArICNhcmVhCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbGF0aXR1ZGVfYW5udWFsX3JhbmdlLnNjYWxlZGFjcm9zc2FsbCArICNsYXRpdHVkZSByYW5nZQogICAgICAgICAgICAgICAgICAgICAgICAgICAgIGxhdGl0dWRlX2FubnVhbF9hdmcuc2NhbGVkYWNyb3NzYWxsICsgI2xhdGl0dWRlIGF2ZwogICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRlcHRoX2FubnVhbF9yYW5nZS5zY2FsZWRhY3Jvc3NhbGwgKyAjZGVwdGggcmFuZ2UKICAgICAgICAgICAgICAgICAgICAgICAgICAgICBkZXB0aF9hbm51YWxfYXZnLnNjYWxlZGFjcm9zc2FsbCArICNkZXB0aCBhdmcKICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzcHBfY291bnRfYW5udWFsLnNjYWxlZGFjcm9zc2FsbCArICNzcHAgIwogICAgICAgICAgICAgICAgICAgICAgICAgICAgIGhhdWxfaWRfY291bnRfYW5udWFsLnNjYWxlZGFjcm9zc2FsbCArCiAgICAgICAgICAgICAgICAgICAgICAgICAgIGp1bGlhbl9zY2FsZWQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZGF0YSA9IGRpc3NpbWlsYXJpdHlfY292YXJpYXRlc19kcmVkZ2UuZHQpCgpnbG9iYWxfbW9kX1NEX3RlbXBfZ2xzIDwtIGdscyhhbm51YWxfZGlzc2ltaWxhcml0eV92YWx1ZSB+IAogICAgICAgICAgICAgICAgICAgICAgICAgICAgIHN1cnZleV91bml0KnllYXJseV9tZWFuX2J5cG9pbnRfU0Quc2NhbGVkYWNyb3NzYWxsICsgI3RlbXAgYW5kIHN1cnZleSB1bml0IChwb3NzaWJsZSBpbnRlcmFjdGlvbikKICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzdXJ2ZXlfdW5pdCpzdW1tZWRfdG9ubmVzX3NjYWxlZF9ieXJlZyArICNmaXNoaW5nIGVmZm9ydCBhbmQgc3VydmV5IHVuaXQgKHBvc3NpYmxlIGludGVyYWN0aW9uKQogICAgICAgICAgICAgICAgICAgICAgICAgICAgIGFyZWFfa20uc2NhbGVkYWNyb3NzYWxsICsgI2FyZWEKICAgICAgICAgICAgICAgICAgICAgICAgICAgICBsYXRpdHVkZV9hbm51YWxfcmFuZ2Uuc2NhbGVkYWNyb3NzYWxsICsgI2xhdGl0dWRlIHJhbmdlCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbGF0aXR1ZGVfYW5udWFsX2F2Zy5zY2FsZWRhY3Jvc3NhbGwgKyAjbGF0aXR1ZGUgYXZnCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZGVwdGhfYW5udWFsX3JhbmdlLnNjYWxlZGFjcm9zc2FsbCArICNkZXB0aCByYW5nZQogICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRlcHRoX2FubnVhbF9hdmcuc2NhbGVkYWNyb3NzYWxsICsgI2RlcHRoIGF2ZwogICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNwcF9jb3VudF9hbm51YWwuc2NhbGVkYWNyb3NzYWxsICsgI3NwcCAjCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaGF1bF9pZF9jb3VudF9hbm51YWwuc2NhbGVkYWNyb3NzYWxsICsKICAgICAgICAgICAgICAgICAgICAgICAgICAganVsaWFuX3NjYWxlZCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29ycmVsYXRpb24gPSBjb3JBUjEoZm9ybT1+eWVhciB8IHN1cnZleV91bml0KSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICBkYXRhID0gZGlzc2ltaWxhcml0eV9jb3ZhcmlhdGVzX2RyZWRnZS5kdCkKClZpZXcoQUlDYyhnbG9iYWxfbW9kX21lYW5fdGVtcF9sbSwgZ2xvYmFsX21vZF9tYXhfdGVtcF9sbSwgZ2xvYmFsX21vZF9taW5fdGVtcF9sbSwgZ2xvYmFsX21vZF9zZWFzX3RlbXBfbG0sIGdsb2JhbF9tb2RfU0RfdGVtcF9sbSwKICAgICAgICAgIGdsb2JhbF9tb2RfbWVhbl90ZW1wX2dscywgZ2xvYmFsX21vZF9tYXhfdGVtcF9nbHMsIGdsb2JhbF9tb2RfbWluX3RlbXBfZ2xzLCBnbG9iYWxfbW9kX3NlYXNfdGVtcF9nbHMsIGdsb2JhbF9tb2RfU0RfdGVtcF9nbHMpKQoKI2J1aWxkIGRhdGEgdGFibGUgdG8gcmVwb3J0IEFJQ2MKZ2xvYmFsX21vZF90ZW1wX3RhYmxlIDwtIGRhdGEudGFibGUoCiAgYFRlbXBvcmFsIGF1dG9jb3JyZWxhdGlvbmAgPSBjKAogICAgYyhyZXAoRiw1KSxyZXAoVCw1KSkKICApLAogIGBUZW1wZXJhdHVyZSB2YXJpYWJsZWAgPSByZXAoYyggICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAiQXZlcmFnZSBtZWFuIFNCVCIsCiAgICAgICAgICAgICAgIkF2ZXJhZ2UgbWF4aW11bSBTQlQiLCAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICJBdmVyYWdlIG1pbmltdW0gU0JUIiwgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAiQXZlcmFnZSBTQlQgc2Vhc29uYWxpdHkiLCAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgIlNCVCBTRCIpLDIpLAogIGRlbHRhQUlDYyA9IHNpZ25pZihtaW4oQUlDYyhnbG9iYWxfbW9kX21lYW5fdGVtcF9sbSwgZ2xvYmFsX21vZF9tYXhfdGVtcF9sbSwgZ2xvYmFsX21vZF9taW5fdGVtcF9sbSwgZ2xvYmFsX21vZF9zZWFzX3RlbXBfbG0sIGdsb2JhbF9tb2RfU0RfdGVtcF9sbSwKICAgICAgICAgIGdsb2JhbF9tb2RfbWVhbl90ZW1wX2dscywgZ2xvYmFsX21vZF9tYXhfdGVtcF9nbHMsIGdsb2JhbF9tb2RfbWluX3RlbXBfZ2xzLCBnbG9iYWxfbW9kX3NlYXNfdGVtcF9nbHMsIGdsb2JhbF9tb2RfU0RfdGVtcF9nbHMpWywyXSktQUlDYyhnbG9iYWxfbW9kX21lYW5fdGVtcF9sbSwgZ2xvYmFsX21vZF9tYXhfdGVtcF9sbSwgZ2xvYmFsX21vZF9taW5fdGVtcF9sbSwgZ2xvYmFsX21vZF9zZWFzX3RlbXBfbG0sIGdsb2JhbF9tb2RfU0RfdGVtcF9sbSwKICAgICAgICAgIGdsb2JhbF9tb2RfbWVhbl90ZW1wX2dscywgZ2xvYmFsX21vZF9tYXhfdGVtcF9nbHMsIGdsb2JhbF9tb2RfbWluX3RlbXBfZ2xzLCBnbG9iYWxfbW9kX3NlYXNfdGVtcF9nbHMsIGdsb2JhbF9tb2RfU0RfdGVtcF9nbHMpWywyXSwyKSkKCiNvcmRlciBieSBhaWNjCnNldG9yZGVyKGdsb2JhbF9tb2RfdGVtcF90YWJsZSxjb2xzID0gLSJkZWx0YUFJQ2MiKQoKZ2xvYmFsX21vZF90ZW1wX3RhYmxlWyxSYW5rIDo9IHNlcSgxLDEwLGJ5ID0gMSldCgpnbG9iYWxfbW9kX3NidF90YWJsZSA8LSBnbG9iYWxfbW9kX3RlbXBfdGFibGVbLC4oUmFuayxgVGVtcG9yYWwgYXV0b2NvcnJlbGF0aW9uYCxgVGVtcGVyYXR1cmUgdmFyaWFibGVgLCBkZWx0YUFJQ2MpXQoKZndyaXRlKGdsb2JhbF9tb2Rfc2J0X3RhYmxlLCBoZXJlOjpoZXJlKCJvdXRwdXQiLCJnbG9iYWxfbW9kX3NidF90YWJsZS5jc3YiKSkKCmBgYAoKQmVzdCBwZXJmb3JtaW5nIGdsb2JhbCBtb2RlbCBpbmNsdWRlcyBtaW5pbXVtIHRlbXBlcmF0dXJlIChjZW50ZXJlZCBhbmQgc2NhbGVkKSAoU3RpbGwgdGhlIGNhc2UgYXMgb2YgTWF5IDYsIDIwMjQpCgpOb3csIGxvb2sgYXQgZGlmZmVyZW50IGNvbWJpbmF0aW9ucyBvZiBhbGwgcHJlZGljdG9ycyAobWluIHRlbXApIHVzaW5nIGRyZWRnZQoKR2xvYmFsIG1vZGVsOiBnbG9iYWxfbW9kX21pbl90ZW1wCgpgYGB7cn0Kb3B0aW9ucyhuYS5hY3Rpb24gPSAibmEuZmFpbCIpICMgIHByZXZlbnQgZml0dGluZyBzdWItbW9kZWxzIHRvIGRpZmZlcmVudCBkYXRhc2V0cwpkZCA8LSBkcmVkZ2UoZ2xvYmFsX21vZF9taW5fdGVtcCkKZGQuZHQgPC0gZGF0YS50YWJsZShkZCkKVmlldyhkZCkKCiNvbmx5IG1vZGVscyBsZXNzIHRoYW4gNCBkZWx0YSBBSUNjICgyIG1vZGVscykKZGQuZHQuMiA8LSBkZC5kdFtkZWx0YSA8PSAyLF0KCmNvbG5hbWVzKGRkLmR0LjIpCgojaW4gdGhpcyBzdGVwLCB3ZSBkZWxldGUgY29lZmZpY2llbnQgdmFsdWVzIGJlY2F1c2Ugd2Ugd2lsbCBwdWxsIHRoZW0gYmFjayBpbiBsYXRlciB3aGVuIHdlIGNhbGN1bGF0ZSBib3RoIFNFIGFuZCBjb2VmZmljaWVudHMgKG90aGVyIHRoYW4gaW50ZXJhY3Rpb24sIHdoaWNoIHdlIGtlZXAgaGVyZSkKZGQuZHQuMi5mb3JtYXR0ZWQgPC0gZGQuZHQuMlssUmFuayA6PSBhcy5udW1lcmljKHJvd25hbWVzKGRkLmR0LjIpKV1bLC4oUmFuaywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBgc3VtbWVkX3Rvbm5lc19zY2FsZWRfYnlyZWc6c3VydmV5X3VuaXRgLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGBzdXJ2ZXlfdW5pdDp5ZWFybHlfbWluX2J5cG9pbnRfYXZnLnNjYWxlZGFjcm9zc2FsbGAsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZGVsdGEsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgd2VpZ2h0LCBzdXJ2ZXlfdW5pdAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICldCgojYWRkIHItc3F1YXJlZCB2YWx1ZXMKIyBJdGVyYXRlIHRocm91Z2ggdGhlIGJlc3QgbW9kZWxzIGFuZCBleHRyYWN0IFItc3F1YXJlZCB2YWx1ZXMKcl9zcXVhcmVkX3ZhbHVlcyA8LWxpc3QoKQpmb3IgKGkgaW4gMTpucm93KGRkLmR0LjIuZm9ybWF0dGVkKSkgewogIHN1bW1hcnlfZGF0YSA8LSBzdW1tYXJ5KGdldC5tb2RlbHMoZGQsIHN1YnNldCA9IGkpW1sxXV0pCiAgcl9zcXVhcmVkIDwtIHNpZ25pZihzdW1tYXJ5X2RhdGEkci5zcXVhcmVkLDIpCiAgcl9zcXVhcmVkX3ZhbHVlcyA8LSB1bmxpc3QoYyhyX3NxdWFyZWRfdmFsdWVzLHJfc3F1YXJlZCkpCn0KCmRkLmR0LjIuZm9ybWF0dGVkWywiUiBzcXVhcmVkIiA6PSByX3NxdWFyZWRfdmFsdWVzXQoKI2VtcHR5IGRhdGEgdGFibGUKCm1vZGVsX2NvZWZfc2VfZmlsbCA8LSBkYXRhLnRhYmxlKFJhbmsgPSBhcy5udW1lcmljKCksIGNvZWZfbmFtZSA9IGFzLmNoYXJhY3RlcigpLGNvZWYgPSBhcy5udW1lcmljKCksIHNlID0gYXMubnVtZXJpYygpKQoKZm9yIChpIGluIDE6bnJvdyhkZC5kdC4yLmZvcm1hdHRlZCkpewogIG1vZGVsX2NvZWZfc2Vfc2luZ2xlIDwtIGRhdGEudGFibGUodW5saXN0KGNvZWZUYWJsZShkZCxmdWxsID0gVClbW2ldXSkpCiAgbW9kZWxfY29lZl9zZV9zaW5nbGVbLGNvZWZfbmFtZXMgOj0gcm93bmFtZXModW5saXN0KGNvZWZUYWJsZShkZCxmdWxsID0gVClbW2ldXSkpXQogIG1vZGVsX2NvZWZfc2Vfc2luZ2xlWyxSYW5rIDo9IGldCiAgCiAgY29sbmFtZXMobW9kZWxfY29lZl9zZV9zaW5nbGUpIDwtIGMoImNvZWYiLCJzZSIsImRmIiwiY29lZl9uYW1lIiwiUmFuayIpCiAgCiAgI3JlZHVjZSB0byBjb2x1bW5zIHdlIG5lZWQKICBtb2RlbF9jb2VmX3NlX3NpbmdsZSA8LSBtb2RlbF9jb2VmX3NlX3NpbmdsZVssLihSYW5rLCBjb2VmX25hbWUsIGNvZWYsIHNlKV0KICAKICBtb2RlbF9jb2VmX3NlX2ZpbGwgPC0gcmJpbmQobW9kZWxfY29lZl9zZV9maWxsLG1vZGVsX2NvZWZfc2Vfc2luZ2xlKQp9CgojZm9ybWF0IHRvIG1lcmdlIHdpdGggbW9kZWwgcmFua2luZ3MgYW5kIGF2ZXJhZ2VkIG1vZGVsCm1vZGVsX2NvZWZfc2VfZmlsbFssY29lZl9zZSA6PSBwYXN0ZTAocm91bmQoY29lZiwzKSwiIMKxICIscm91bmQoc2UsMykpXQoKI2RlbGV0ZSBleHRyYSBjb2x1bW5zCm1vZGVsX2NvZWZfc2VfZmlsbCA8LSBtb2RlbF9jb2VmX3NlX2ZpbGxbLC4oUmFuayxjb2VmX25hbWUsY29lZl9zZSldCgojbG9uZyB0byB3aWRlCm1vZGVsX2NvZWZfc2VfZmlsbC53IDwtIGRjYXN0KG1vZGVsX2NvZWZfc2VfZmlsbCwgZm9ybXVsYSA9IFJhbmsgfiBjb2VmX25hbWUsIHZhbHVlLnZhciA9IGMoImNvZWZfc2UiKSkKCiNtZXJnZSBtb2RlbF9jb2VmX3NlX2ZpbGwgd2l0aCBkZC5kdC4yLmZvcm1hdHRlZAptb2RlbF9jb2VmX3NlX0FJQyA8LSBkZC5kdC4yLmZvcm1hdHRlZFttb2RlbF9jb2VmX3NlX2ZpbGwudywgb24gPSAiUmFuayJdCgojbW9kZWwgYXZlcmFnZSBhbGwgbW9kZWxzIHdpdGggZGVsdGEgPCA0ICg1MCBtb2RlbHMpCm1vZGVsX2F2Z19kZWx0YTQgPC1tb2RlbC5hdmcoZGQsIHN1YnNldCA9IGRlbHRhIDwgNCwgZml0ID0gVCkgI05COiBUaGUg4oCYc3Vic2V04oCZIChvciDigJhjb25kaXRpb25hbOKAmSkgYXZlcmFnZSBvbmx5ICAgYXZlcmFnZXMgb3ZlciB0aGUgbW9kZWxzIHdoZXJlIHRoZSBwYXJhbWV0ZXIgYXBwZWFycy4gQW4gYWx0ZXJuYXRpdmUsIHRoZSDigJhmdWxs4oCZIGF2ZXJhZ2UgYXNzdW1lcyB0aGF0IGEgdmFyaWFibGUgaXMgaW5jbHVkZWQgaW4gZXZlcnkgbW9kZWwsIGJ1dCBpbiBzb21lIG1vZGVscyB0aGUgY29ycmVzcG9uZGluZyBjb2VmZmljaWVudCAoYW5kIGl0cyByZXNwZWN0aXZlIHZhcmlhbmNlKSBpcyBzZXQgdG8gemVyby4gVW5saWtlIHRoZSDigJhzdWJzZXQgYXZlcmFnZeKAmSwgaXQgZG9lcyBub3QgaGF2ZSBhIHRlbmRlbmN5IG9mIGJpYXNpbmcgdGhlIHZhbHVlIGF3YXkgZnJvbSB6ZXJvLiBUaGUg4oCYZnVsbOKAmSBhdmVyYWdlIGlzIGEgdHlwZSBvZiBzaHJpbmthZ2UgZXN0aW1hdG9yLCBhbmQgZm9yIHZhcmlhYmxlcyB3aXRoIGEgd2VhayByZWxhdGlvbnNoaXAgdG8gdGhlIHJlc3BvbnNlIGl0IGlzIHNtYWxsZXIgdGhhbiDigJhzdWJzZXTigJkgZXN0aW1hdG9ycy4sIGZpdCA9IFQgZml0cyB0aGUgY29tcG9uZW50IG1vZGVscyBhZ2FpbgoKbW9kZWxfYXZnX3ZhbHVlcyA8LSBhcy5kYXRhLnRhYmxlKGNvZWZUYWJsZShtb2RlbF9hdmdfZGVsdGE0LGZpbGwgPSBUKSkgIyB3aXRoIFNFCmNvZWZfbmFtZXMgPC0gbmFtZXMoY29lZihtb2RlbC5hdmcoZGQsIHN1YnNldCA9IGRlbHRhIDwgNCkpKQptb2RlbF9hdmdfdmFsdWVzWyxjb2VmX25hbWU6PWNvZWZfbmFtZXNdWyxjb2VmOj1Fc3RpbWF0ZV1bLEVzdGltYXRlOj1OVUxMXVssZGY6PU5VTExdWyxzZTo9IGBTdGQuIEVycm9yYF1bLGBTdGQuIEVycm9yYCA6PSBOVUxMXQoKI25ldyBjb2x1bW4gd2l0aCBjb2VmIGFuZCBTRQptb2RlbF9hdmdfdmFsdWVzWyxjb2VmX3NlIDo9IHBhc3RlMChyb3VuZChjb2VmLDMpLCIgwrEgIixyb3VuZChzZSwzKSldCgojbG9uZyB0byB3aWRlIGZvciBtb2RlbCBhdmcKbW9kZWxfYXZnLndpZGUgPC0gZGNhc3QobW9kZWxfYXZnX3ZhbHVlcywgZm9ybXVsYSA9IC4gfiBjb2VmX25hbWUsIHZhbHVlLnZhciA9IGMoImNvZWZfc2UiKSkKCiNhZGQgcmFuayBvZiAibW9kZWwgYXZnIiB0byB0YWJsZQptb2RlbF9hdmcud2lkZVssUmFuayA6PSAiTW9kZWwgYXZnIl0KCmJlc3RfbW9kZWxfc2J0X2phY2NhcmRfdGFibGVfZm9ybWF0dGVkIDwtIHJiaW5kKG1vZGVsX2NvZWZfc2VfQUlDLCBtb2RlbF9hdmcud2lkZSwgZmlsbCA9IFQpCgojZ2V0IHJpZCBvZiBpbnRlcmFjdGlvbiBjb2VmZmljaWVudHMKYmVzdF9tb2RlbF9zYnRfamFjY2FyZF90YWJsZV9mb3JtYXR0ZWQuciA8LSBiZXN0X21vZGVsX3NidF9qYWNjYXJkX3RhYmxlX2Zvcm1hdHRlZFssLihSYW5rLGAoSW50ZXJjZXB0KWAsYXJlYV9rbS5zY2FsZWRhY3Jvc3NhbGwsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZGVwdGhfYW5udWFsX2F2Zy5zY2FsZWRhY3Jvc3NhbGwsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZGVwdGhfYW5udWFsX3JhbmdlLnNjYWxlZGFjcm9zc2FsbCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBoYXVsX2lkX2NvdW50X2FubnVhbC5zY2FsZWRhY3Jvc3NhbGwsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAganVsaWFuX3NjYWxlZCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBsYXRpdHVkZV9hbm51YWxfYXZnLnNjYWxlZGFjcm9zc2FsbCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBsYXRpdHVkZV9hbm51YWxfcmFuZ2Uuc2NhbGVkYWNyb3NzYWxsLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNwcF9jb3VudF9hbm51YWwuc2NhbGVkYWNyb3NzYWxsLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHN1bW1lZF90b25uZXNfc2NhbGVkX2J5cmVnLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHN1cnZleV91bml0LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHllYXJseV9taW5fYnlwb2ludF9hdmcuc2NhbGVkYWNyb3NzYWxsLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGBzdW1tZWRfdG9ubmVzX3NjYWxlZF9ieXJlZzpzdXJ2ZXlfdW5pdGAsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYHN1cnZleV91bml0OnllYXJseV9taW5fYnlwb2ludF9hdmcuc2NhbGVkYWNyb3NzYWxsYCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBgUiBzcXVhcmVkYCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBkZWx0YSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB3ZWlnaHQKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICApXQoKI3JvdW5kIHRvIDIgc2lnbmlmaWNhbnQgZmlndXJlcwoKI25hbWVzIG9mIG51bWVyaWMgY29sdW1ucwpudW1lcmljX2NvbHMgPC0gbmFtZXMoYmVzdF9tb2RlbF9zYnRfamFjY2FyZF90YWJsZV9mb3JtYXR0ZWQucilbc2FwcGx5KGJlc3RfbW9kZWxfc2J0X2phY2NhcmRfdGFibGVfZm9ybWF0dGVkLnIsIGlzLm51bWVyaWMpXQoKIyBBcHBseSBzaWduaWYoKSBvbmx5IHRvIG51bWVyaWMgY29sdW1ucwpiZXN0X21vZGVsX3NidF9qYWNjYXJkX3RhYmxlX2Zvcm1hdHRlZC5yWywgKG51bWVyaWNfY29scykgOj0gbGFwcGx5KC5TRCwgZnVuY3Rpb24oeCkgaWYgKGlzLm51bWVyaWMoeCkpIHNpZ25pZih4LCBkaWdpdHMgPSAyKSBlbHNlIHgpLCAuU0Rjb2xzID0gbnVtZXJpY19jb2xzXQoKI2NoYW5nZSBjb2x1bW4gbmFtZXMsIGluIGNhcHRpb24gbm90ZSB0aGF0IGFsbCB2YXJpYWJsZXMgYXJlIGNlbnRlcmVkIGFuZCBzY2FsZWQKY29sbmFtZXMoYmVzdF9tb2RlbF9zYnRfamFjY2FyZF90YWJsZV9mb3JtYXR0ZWQucikgPC0gYygKIlJhbmsiLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKIkludGVyY2VwdCIsICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAoiQXJlYSIsICAgICAgICNzY2FsZWQgYWNyb3NzIGFsbCAgICAgICAgICAgICAgICAgICAgCiJBdmVyYWdlIGRlcHRoIiwgICAgICAgICAgICAgICAgICAKIkRlcHRoIHJhbmdlIiwgICAgICAgICAgICAgICAgCiJOdW1iZXIgb2YgdG93cyIsICAgICAKIkF2ZXJhZ2UgSnVsaWFuIGRheSIsCiJBdmVyYWdlIGxhdGl0dWRlIiwgICAgICAgICAgICAgICAKIkxhdGl0dWRlIHJhbmdlIiwgICAgICAgICAgICAgCiJTcGVjaWVzIGNvdW50IiwgICAgICAgICAgICAgICAgICAKIlJlbGF0aXZlIGNhdGNoIiwgI3NjYWxlZCB3aXRoaW4gcmVnaW9uICAgICAgICAgICAgICAgICAgICAgICAKIlN1cnZleSIsICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiJBdmVyYWdlIG1pbmltdW0gdGVtcGVyYXR1cmUiLCAgICAgICAgICAgIAoiU3VydmV5ICogcmVsYXRpdmUgY2F0Y2giLCAgICAgICAgICAgIAoiU3VydmV5ICogYXZnIG1pbiB0ZW1wZXJhdHVyZSIsCiJSIHNxdWFyZWQiLApwYXN0ZTAoIlx1MDM5NCIsIiBBSUNjIiksICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCnBhc3RlMCgiXHUwM0M5IikpCgoKCiNzYXZlIGFzIGNzdgoKZndyaXRlKGJlc3RfbW9kZWxfc2J0X2phY2NhcmRfdGFibGVfZm9ybWF0dGVkLnIsaGVyZTo6aGVyZSgib3V0cHV0IiwiYmVzdF9tb2RlbF9zYnRfamFjY2FyZF90YWJsZV9mb3JtYXR0ZWQuY3N2IikpCmBgYAoKClRha2UgYXdheXMKRGlzc2ltaWxhcml0eSBpbmNyZWFzZXMgd2l0aCBpbmNyZWFzaW5nIGF2ZyAjIHRvd3MKRGlzc2ltaWxhcml0eSBkZWNyZWFzZXMgd2l0aCBpbmNyZWFzaW5nIGF2ZyBsYXRpdHVkZQpEaXNzaW1pbGFyaXR5IGRlY3JlYXNlcyB3aXRoIGluY3JlYXNpbmcgSnVsaWFuIGRheSBvZiBzYW1wbGluZwpEaXNzaW1pbGFyaXR5IGluY3JlYXNlcyB3aXRoIGluY3JlYXNpbmcgbGF0aXR1ZGUgcmFuZ2UKRGlzc2ltaWxhcml0eSBpbmNyZWFzZXMgd2l0aCBpbmNyZWFzaW5nIGZpc2hpbmcgZWZmb3J0CkRpc3NpbWlsYXJpdHkgZGVjcmVhc2VzIHdpdGggaW5jcmVhc2luZyBkZXB0aCByYW5nZQpEaXNzaW1pbGFyaXR5ICBpbmNyZWFzZXMgd2l0aCBpbmNyZWFzaW5nIGF2ZXJhZ2UgZGVwdGgKRGlzc2ltaWxhcml0eSBpbmNyZWFzZXMgd2l0aCBpbmNyZWFzaW5nIGFyZWEKRGlzc2ltaWxhcml0eSAgZGVjcmVhc2VzIHdpdGggaW5jcmVhc2luZyBtaW5pbXVtIHRlbXBlcmF0dXJlCkRpc3NpbWlsYXJpdHkgaW5jcmVhc2VzIHdpdGggaW5jcmVhc2luZyAjIHNwcApEaXNzaW1pbGFyaXR5IGluY3JlYXNlcyB3aXRoIHJlbGF0aXZlIGZpc2hpbmcgY2F0Y2gKCgoKUHJlZGljdCBkaXNzaW1pbGFyaXR5IGFjcm9zcyB5ZWFycyB1c2luZyBhdmVyYWdlZCBtb2RlbCAobW9kZWxfYXZnX2RlbHRhNCkKYGBge3J9CmRpc3NpbWlsYXJpdHlfY292YXJpYXRlc19kcmVkZ2UuZHRfcHJlZGljdGlvbnMgPC0gY29weShkaXNzaW1pbGFyaXR5X2NvdmFyaWF0ZXNfZHJlZGdlLmR0KQoKICAjYWxsb3dpbmcgdGVtcCBhbmQgZmlzaGluZyB0byB2YXJ5IChha2Egbm8gY2hhbmdlcykKICBkaXNzaW1pbGFyaXR5X2NvdmFyaWF0ZXNfZHJlZGdlLmR0X3ByZWRpY3Rpb25zWyxwcmVkX2Rpc3NpbSA6PSBwcmVkaWN0KG1vZGVsX2F2Z19kZWx0YTQsIHNlLmZpdCA9IFQsIGZ1bGwgPSBGKVtbMV1dXVsscHJlZF9zZSA6PSBwcmVkaWN0KG1vZGVsX2F2Z19kZWx0YTQsIHNlLmZpdCA9IFQsIGZ1bGwgPSBGKVtbMl1dXSAjZnVsbCBhbGxvd3MgdXMgdG8gc3dpdGNoIGJhY2sgdG8gbWl4ZWQgZWZmZWN0IG1vZGVscwogIAogIAogIAogICNjb25zdGFudCB0ZW1wIGluIHJlZ2lvbnMgKGFrYSB0YWtlIG1lYW4gb2YgdGVtcGVyYXR1cmUgdmFsdWVzIHdpdGhpbiBzdXJ2ZXkgdW5pdHMgc28gdGhleSBhcmUgdGhlIHNhbWUgdmFsdWUgd2l0aGluIGVhY2ggeWVhciBmb3IgYSBzdXJ2ZXkpCiAgZGlzc2ltaWxhcml0eV9jb3ZhcmlhdGVzX2RyZWRnZS5kdF9wcmVkaWN0aW9uc19jb25zaXN0ZW50dGVtcGlucmVnIDwtIGNvcHkoZGlzc2ltaWxhcml0eV9jb3ZhcmlhdGVzX2RyZWRnZS5kdCkKICBkaXNzaW1pbGFyaXR5X2NvdmFyaWF0ZXNfZHJlZGdlLmR0X3ByZWRpY3Rpb25zX2NvbnNpc3RlbnR0ZW1waW5yZWdbLHllYXJseV9taW5fYnlwb2ludF9hdmcuc2NhbGVkYWNyb3NzYWxsOj1tZWFuKHllYXJseV9taW5fYnlwb2ludF9hdmcuc2NhbGVkYWNyb3NzYWxsKSwuKHN1cnZleV91bml0KV0KCiAgI2NvbnN0YW50IGZpc2hpbmcgaW4gcmVnaW9ucyAoYWthIHRha2UgbWVhbiBvZiBmaXNoaW5nIHZhbHVlcyB3aXRoaW4gc3VydmV5IHVuaXRzIHNvIHRoZXkgYXJlIHRoZSBzYW1lIHZhbHVlIHdpdGhpbiBlYWNoIHllYXIgZm9yIGEgc3VydmV5KQogIGRpc3NpbWlsYXJpdHlfY292YXJpYXRlc19kcmVkZ2UuZHRfcHJlZGljdGlvbnNfY29uc2lzdGVudGZpc2hpbmdpbnJlZyA8LSBjb3B5KGRpc3NpbWlsYXJpdHlfY292YXJpYXRlc19kcmVkZ2UuZHQpCiAgZGlzc2ltaWxhcml0eV9jb3ZhcmlhdGVzX2RyZWRnZS5kdF9wcmVkaWN0aW9uc19jb25zaXN0ZW50ZmlzaGluZ2lucmVnWyxzdW1tZWRfdG9ubmVzX3NjYWxlZF9ieXJlZzo9bWVhbihzdW1tZWRfdG9ubmVzX3NjYWxlZF9ieXJlZyksLihzdXJ2ZXlfdW5pdCldCgojYW5kIHRoZW4gd2l0aCBjb25zaXN0ZW50IHRlbXAgYW5kIGZpc2hpbmcgaW4gcmVnaW9ucyAoYWthIHRha2UgbWVhbiBvZiBib3RoIG1pbiB0ZW1wIGFuZCBmaXNoaW5nKQpkaXNzaW1pbGFyaXR5X2NvdmFyaWF0ZXNfZHJlZGdlLmR0X3ByZWRpY3Rpb25zX2NvbnNpc3RlbnR0ZW1wZmlzaGluZ2lucmVnIDwtIGNvcHkoZGlzc2ltaWxhcml0eV9jb3ZhcmlhdGVzX2RyZWRnZS5kdCkKZGlzc2ltaWxhcml0eV9jb3ZhcmlhdGVzX2RyZWRnZS5kdF9wcmVkaWN0aW9uc19jb25zaXN0ZW50dGVtcGZpc2hpbmdpbnJlZ1ssc3VtbWVkX3Rvbm5lc19zY2FsZWRfYnlyZWc6PW1lYW4oc3VtbWVkX3Rvbm5lc19zY2FsZWRfYnlyZWcpLC4oc3VydmV5X3VuaXQpXVsseWVhcmx5X21pbl9ieXBvaW50X2F2Zy5zY2FsZWRhY3Jvc3NhbGw6PW1lYW4oeWVhcmx5X21pbl9ieXBvaW50X2F2Zy5zY2FsZWRhY3Jvc3NhbGwpLC4oc3VydmV5X3VuaXQpXQoKCiNhbGxvd2luZyB0ZW1wIGFuZCBmaXNoaW5nIHRvIHZhcnkgd2l0aGluIHJlZ3MgKG5vcm1hbCkKICAgIGRpc3NpbWlsYXJpdHlfY292YXJpYXRlc19kcmVkZ2UuZHRfcHJlZGljdGlvbnNbLHByZWRfZGlzc2ltIDo9IAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHByZWRpY3QobW9kZWxfYXZnX2RlbHRhNCwgc2UuZml0ID0gVCwgZnVsbCA9IEYsIG5ld2RhdGEgPSAgIGRpc3NpbWlsYXJpdHlfY292YXJpYXRlc19kcmVkZ2UuZHRfcHJlZGljdGlvbnMpW1sxXV1dWyxwcmVkX3NlIDo9IAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcHJlZGljdChtb2RlbF9hdmdfZGVsdGE0LCBzZS5maXQgPSBULCBmdWxsID0gRiwgbmV3ZGF0YSA9ICAgZGlzc2ltaWxhcml0eV9jb3ZhcmlhdGVzX2RyZWRnZS5kdF9wcmVkaWN0aW9ucylbWzJdXV0KICAKI2FsbG93aW5nIG9ubHkgZmlzaGluZyB0byB2YXJ5IHdpdGhpbiByZWdpb25zICh3aXRoIG1lYW4gdGVtcCkKICAKICAgZGlzc2ltaWxhcml0eV9jb3ZhcmlhdGVzX2RyZWRnZS5kdF9wcmVkaWN0aW9uc19jb25zaXN0ZW50dGVtcGlucmVnWyxwcmVkX2Rpc3NpbSA6PSAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcHJlZGljdChtb2RlbF9hdmdfZGVsdGE0LCBzZS5maXQgPSBULCBmdWxsID0gRiwgbmV3ZGF0YSA9IGRpc3NpbWlsYXJpdHlfY292YXJpYXRlc19kcmVkZ2UuZHRfcHJlZGljdGlvbnNfY29uc2lzdGVudHRlbXBpbnJlZylbWzFdXV1bLHByZWRfc2UgOj0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBwcmVkaWN0KG1vZGVsX2F2Z19kZWx0YTQsIHNlLmZpdCA9IFQsIGZ1bGwgPSBGLCBuZXdkYXRhID0gZGlzc2ltaWxhcml0eV9jb3ZhcmlhdGVzX2RyZWRnZS5kdF9wcmVkaWN0aW9uc19jb25zaXN0ZW50dGVtcGlucmVnKVtbMl1dXQoKICAKICAKI2FsbG93aW5nIG9ubHkgdGVtcGVyYXR1cmUgdG8gdmFyeSB3aXRoaW4gcmVnaW9ucyAod2l0aCBtZWFuIGZpc2hpbmcgcHJlc3N1cmUpCiAgICAgCiAgIGRpc3NpbWlsYXJpdHlfY292YXJpYXRlc19kcmVkZ2UuZHRfcHJlZGljdGlvbnNfY29uc2lzdGVudGZpc2hpbmdpbnJlZ1sscHJlZF9kaXNzaW0gOj0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcHJlZGljdChtb2RlbF9hdmdfZGVsdGE0LCBzZS5maXQgPSBULCBmdWxsID0gRiwgbmV3ZGF0YSA9IGRpc3NpbWlsYXJpdHlfY292YXJpYXRlc19kcmVkZ2UuZHRfcHJlZGljdGlvbnNfY29uc2lzdGVudGZpc2hpbmdpbnJlZylbWzFdXV1bLHByZWRfc2UgOj0gCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBwcmVkaWN0KG1vZGVsX2F2Z19kZWx0YTQsIHNlLmZpdCA9IFQsIGZ1bGwgPSBGLCBuZXdkYXRhID0gZGlzc2ltaWxhcml0eV9jb3ZhcmlhdGVzX2RyZWRnZS5kdF9wcmVkaWN0aW9uc19jb25zaXN0ZW50ZmlzaGluZ2lucmVnKVtbMl1dXQogICAKI2FuZCB0aGVuIHdpdGggY29uc2lzdGVudCB0ZW1wIGFuZCBmaXNoaW5nIGFjcm9zcyByZWdpb25zIChtZWFuIG9mIGJvdGggZmlzaGluZyBhbmQgdGVtcCkKZGlzc2ltaWxhcml0eV9jb3ZhcmlhdGVzX2RyZWRnZS5kdF9wcmVkaWN0aW9uc19jb25zaXN0ZW50dGVtcGZpc2hpbmdpbnJlZyA8LSBjb3B5KGRpc3NpbWlsYXJpdHlfY292YXJpYXRlc19kcmVkZ2UuZHQpCmRpc3NpbWlsYXJpdHlfY292YXJpYXRlc19kcmVkZ2UuZHRfcHJlZGljdGlvbnNfY29uc2lzdGVudHRlbXBmaXNoaW5naW5yZWdbLHN1bW1lZF90b25uZXNfc2NhbGVkX2J5cmVnOj1tZWFuKHN1bW1lZF90b25uZXNfc2NhbGVkX2J5cmVnKSwuKHN1cnZleV91bml0KV1bLHllYXJseV9taW5fYnlwb2ludF9hdmcuc2NhbGVkYWNyb3NzYWxsOj1tZWFuKHllYXJseV9taW5fYnlwb2ludF9hdmcuc2NhbGVkYWNyb3NzYWxsKSwuKHN1cnZleV91bml0KV0KCmRpc3NpbWlsYXJpdHlfY292YXJpYXRlc19kcmVkZ2UuZHRfcHJlZGljdGlvbnNfY29uc2lzdGVudHRlbXBmaXNoaW5naW5yZWdbLHByZWRfZGlzc2ltIDo9IAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcHJlZGljdChtb2RlbF9hdmdfZGVsdGE0LCBzZS5maXQgPSBULCBmdWxsID0gRiwgbmV3ZGF0YSA9IGRpc3NpbWlsYXJpdHlfY292YXJpYXRlc19kcmVkZ2UuZHRfcHJlZGljdGlvbnNfY29uc2lzdGVudHRlbXBmaXNoaW5naW5yZWcpW1sxXV1dWyxwcmVkX3NlIDo9CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcHJlZGljdChtb2RlbF9hdmdfZGVsdGE0LCBzZS5maXQgPSBULCBmdWxsID0gRiwgbmV3ZGF0YSA9IGRpc3NpbWlsYXJpdHlfY292YXJpYXRlc19kcmVkZ2UuZHRfcHJlZGljdGlvbnNfY29uc2lzdGVudHRlbXBmaXNoaW5naW5yZWcpW1syXV1dCgoKI2FuZCB0aGVuIHdpdGggY29uc2lzdGVudCB0ZW1wIGFuZCBmaXNoaW5nIGFjcm9zcyByZWdpb25zIChtZWFuIG9mIGJvdGggZmlzaGluZyBhbmQgdGVtcCkKZGlzc2ltaWxhcml0eV9jb3ZhcmlhdGVzX2RyZWRnZS5kdF9wcmVkaWN0aW9uc19jb25zaXN0ZW50dGVtcGZpc2hpbmcgPC0gY29weShkaXNzaW1pbGFyaXR5X2NvdmFyaWF0ZXNfZHJlZGdlLmR0KQpkaXNzaW1pbGFyaXR5X2NvdmFyaWF0ZXNfZHJlZGdlLmR0X3ByZWRpY3Rpb25zX2NvbnNpc3RlbnR0ZW1wZmlzaGluZ1ssc3VtbWVkX3Rvbm5lc19zY2FsZWRfYnlyZWc6PW1lYW4oc3VtbWVkX3Rvbm5lc19zY2FsZWRfYnlyZWcpXVsseWVhcmx5X21pbl9ieXBvaW50X2F2Zy5zY2FsZWRhY3Jvc3NhbGw6PW1lYW4oeWVhcmx5X21pbl9ieXBvaW50X2F2Zy5zY2FsZWRhY3Jvc3NhbGwpXQoKZGlzc2ltaWxhcml0eV9jb3ZhcmlhdGVzX2RyZWRnZS5kdF9wcmVkaWN0aW9uc19jb25zaXN0ZW50dGVtcGZpc2hpbmdbLHByZWRfZGlzc2ltIDo9IAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcHJlZGljdChtb2RlbF9hdmdfZGVsdGE0LCBzZS5maXQgPSBULCBmdWxsID0gRiwgbmV3ZGF0YSA9IGRpc3NpbWlsYXJpdHlfY292YXJpYXRlc19kcmVkZ2UuZHRfcHJlZGljdGlvbnNfY29uc2lzdGVudHRlbXBmaXNoaW5nKVtbMV1dXVsscHJlZF9zZSA6PQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHByZWRpY3QobW9kZWxfYXZnX2RlbHRhNCwgc2UuZml0ID0gVCwgZnVsbCA9IEYsIG5ld2RhdGEgPSBkaXNzaW1pbGFyaXR5X2NvdmFyaWF0ZXNfZHJlZGdlLmR0X3ByZWRpY3Rpb25zX2NvbnNpc3RlbnR0ZW1wZmlzaGluZylbWzJdXV0KCiNGT1IgQ09MT1IgVE8gTUFUQ0gKI3NvcnQgY29sb3IgbGluayBieSBzdXJ2ZXkgbmFtZSBzZWFzb24KI2FscGhhYmV0aWNhbCBvcmRlcgpjb2xvcl9saW5rX2FscGhhIDwtIHNldG9yZGVyKGNvbG9yX2xpbmssIHN1cnZleV91bml0KQoKI2V4Y2x1ZGUgc3VydmV5cyB3ZSBkb24ndCBpbmNsdWRlCmNvbG9yX2xpbmtfYWxwaGEgPC0gY29sb3JfbGlua19hbHBoYVtzdXJ2ZXlfdW5pdCAlaW4lIHVuaXF1ZShkaXNzaW1pbGFyaXR5X2NvdmFyaWF0ZXNfZHJlZGdlLmR0X3ByZWRpY3Rpb25zJHN1cnZleV91bml0KSxdCgpjb2xvcl9hbHBoYV9vcmRlciA8LSBjb2xvcl9saW5rX2FscGhhWyxoZXhdCmxhYmVsX2FscGhhX29yZGVyIDwtIGNvbG9yX2xpbmtfYWxwaGFbLFN1cnZleV9OYW1lX1NlYXNvbl0KICAKCiNtYWludGFpbiB0ZW1wIGFuZCBmaXNoaW5nCiNwbG90CnByZWRpY3RlZF92YWx1ZXNfdGVtcF9maXNoaW5nIDwtIGdncGxvdChkaXNzaW1pbGFyaXR5X2NvdmFyaWF0ZXNfZHJlZGdlLmR0X3ByZWRpY3Rpb25zKSArCiAgZ2VvbV9wb2ludChhZXMoeCA9IHllYXIsIHkgPSBhbm51YWxfZGlzc2ltaWxhcml0eV92YWx1ZSwgY29sb3IgPSBzdXJ2ZXlfdW5pdCkpICsKICBnZW9tX2xpbmUoYWVzKHggPSB5ZWFyLCB5ID0gcHJlZF9kaXNzaW0sIGNvbG9yID0gc3VydmV5X3VuaXQpKSArCiAgZ2VvbV9yaWJib24oYWVzKHggPSB5ZWFyLCB5bWluID0gcHJlZF9kaXNzaW0tcHJlZF9zZSwgeW1heCA9IHByZWRfZGlzc2ltK3ByZWRfc2UsIGZpbGwgPSBzdXJ2ZXlfdW5pdCksIGFscGhhID0gMC4zKSArCiAgc2NhbGVfY29sb3JfbWFudWFsKHZhbHVlcyA9IGNvbG9yX2FscGhhX29yZGVyLCBsYWJlbHMgPSBsYWJlbF9hbHBoYV9vcmRlciwgbmFtZSA9ICJTdXJ2ZXkiKSArCiAgc2NhbGVfZmlsbF9tYW51YWwodmFsdWVzID0gY29sb3JfYWxwaGFfb3JkZXIsIGxhYmVscyA9IGxhYmVsX2FscGhhX29yZGVyLCBuYW1lID0gIlN1cnZleSIpICsKICBsYWJzKHggPSAiWWVhciIseSA9ICJBdmVyYWdlIGFubnVhbCB0b3RhbFxuQnJheSBDdXJ0aXMgZGlzc2ltaWxhcml0eSIpICsKICB5bGltKDAsMS41KSArCiAgdGhlbWVfY2xhc3NpYygpICsKICBnZ3RpdGxlKCJBdmVyYWdlIG1vZGVsIHByZWRpY3Rpb25zIikKCiNhdmVyYWdlIHRlbXAgYW5kIGZpc2hpbmcgZm9yIGVhY2ggcmVnaW9uCnByZWRpY3RlZF92YWx1ZXNfdGVtcF9maXNoaW5nX21lYW50ZW1wZmlzaGluZ2luc3VydmV5IDwtIGdncGxvdChkaXNzaW1pbGFyaXR5X2NvdmFyaWF0ZXNfZHJlZGdlLmR0X3ByZWRpY3Rpb25zX2NvbnNpc3RlbnR0ZW1wZmlzaGluZ2lucmVnKSArCiAgZ2VvbV9wb2ludChhZXMoeCA9IHllYXIsIHkgPSBhbm51YWxfZGlzc2ltaWxhcml0eV92YWx1ZSwgY29sb3IgPSBzdXJ2ZXlfdW5pdCkpICsKICBnZW9tX2xpbmUoYWVzKHggPSB5ZWFyLCB5ID0gcHJlZF9kaXNzaW0sIGNvbG9yID0gc3VydmV5X3VuaXQpKSArCiAgZ2VvbV9yaWJib24oYWVzKHggPSB5ZWFyLCB5bWluID0gcHJlZF9kaXNzaW0tcHJlZF9zZSwgeW1heCA9IHByZWRfZGlzc2ltK3ByZWRfc2UsIGZpbGwgPSBzdXJ2ZXlfdW5pdCksIGFscGhhID0gMC4zKSArCiAgc2NhbGVfY29sb3JfbWFudWFsKHZhbHVlcyA9IGNvbG9yX2FscGhhX29yZGVyLCBsYWJlbHMgPSBsYWJlbF9hbHBoYV9vcmRlciwgbmFtZSA9ICJTdXJ2ZXkiKSArCiAgc2NhbGVfZmlsbF9tYW51YWwodmFsdWVzID0gY29sb3JfYWxwaGFfb3JkZXIsIGxhYmVscyA9IGxhYmVsX2FscGhhX29yZGVyLCBuYW1lID0gIlN1cnZleSIpICsKICBsYWJzKHggPSAiWWVhciIseSA9ICJBdmVyYWdlIGFubnVhbCB0b3RhbFxuQnJheSBDdXJ0aXMgZGlzc2ltaWxhcml0eSIpICsKICB5bGltKDAsMS41KSArCiAgdGhlbWVfY2xhc3NpYygpICsKICBnZ3RpdGxlKCJBdmVyYWdlIG1vZGVsIHByZWRpY3Rpb25zIHdpdGggbWVhblxuc3VydmV5IHRlbXBlcmF0dXJlIGFuZCBmaXNoaW5nIHByZXNzdXJlIikKCiNhdmVyYWdlIHRlbXAgYW5kIGZpc2hpbmcgYWNyb3NzIGFsbCByZWdpb25zCnByZWRpY3RlZF92YWx1ZXNfdGVtcF9maXNoaW5nX21lYW50ZW1wZmlzaGluZyA8LSBnZ3Bsb3QoZGlzc2ltaWxhcml0eV9jb3ZhcmlhdGVzX2RyZWRnZS5kdF9wcmVkaWN0aW9uc19jb25zaXN0ZW50dGVtcGZpc2hpbmcpICsKICBnZW9tX3BvaW50KGFlcyh4ID0geWVhciwgeSA9IGFubnVhbF9kaXNzaW1pbGFyaXR5X3ZhbHVlLCBjb2xvciA9IHN1cnZleV91bml0KSkgKwogIGdlb21fbGluZShhZXMoeCA9IHllYXIsIHkgPSBwcmVkX2Rpc3NpbSwgY29sb3IgPSBzdXJ2ZXlfdW5pdCkpICsKICBnZW9tX3JpYmJvbihhZXMoeCA9IHllYXIsIHltaW4gPSBwcmVkX2Rpc3NpbS1wcmVkX3NlLCB5bWF4ID0gcHJlZF9kaXNzaW0rcHJlZF9zZSwgZmlsbCA9IHN1cnZleV91bml0KSwgYWxwaGEgPSAwLjEpICsKICBzY2FsZV9jb2xvcl9tYW51YWwodmFsdWVzID0gY29sb3JfYWxwaGFfb3JkZXIsIGxhYmVscyA9IGxhYmVsX2FscGhhX29yZGVyLCBuYW1lID0gIlN1cnZleSIpICsKICBzY2FsZV9maWxsX21hbnVhbCh2YWx1ZXMgPSBjb2xvcl9hbHBoYV9vcmRlciwgbGFiZWxzID0gbGFiZWxfYWxwaGFfb3JkZXIsIG5hbWUgPSAiU3VydmV5IikgKwogIGxhYnMoeCA9ICJZZWFyIix5ID0gIkF2ZXJhZ2UgYW5udWFsIHRvdGFsXG5CcmF5IEN1cnRpcyBkaXNzaW1pbGFyaXR5IikgKwogIHlsaW0oMCwxLjUpICsKICB0aGVtZV9jbGFzc2ljKCkgKwogIGdndGl0bGUoIkF2ZXJhZ2UgbW9kZWwgcHJlZGljdGlvbnMgd2l0aCBtZWFuXG5vdmVyZWFsbCB0ZW1wZXJhdHVyZSBhbmQgZmlzaGluZyBwcmVzc3VyZSIpCgojbWVyZ2UgcGxvdHMKcHJlZGljdGVkX3ZhbHVlc19zYnRfamFjY2FyZF9maXNoaW5nX21lcmdlIDwtIGNvd3Bsb3Q6OnBsb3RfZ3JpZChwcmVkaWN0ZWRfdmFsdWVzX3RlbXBfZmlzaGluZywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHByZWRpY3RlZF92YWx1ZXNfdGVtcF9maXNoaW5nX21lYW50ZW1wZmlzaGluZ2luc3VydmV5LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcHJlZGljdGVkX3ZhbHVlc190ZW1wX2Zpc2hpbmdfbWVhbnRlbXBmaXNoaW5nLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbmNvbCA9IDEpCgpnZ3NhdmUocHJlZGljdGVkX3ZhbHVlc19zYnRfamFjY2FyZF9maXNoaW5nX21lcmdlLCBwYXRoID0gaGVyZTo6aGVyZSgiZmlndXJlcyIpLCBmaWxlbmFtZSA9ICJwcmVkaWN0ZWRfdmFsdWVzX3NidF9qYWNjYXJkX2Zpc2hpbmdfbWVyZ2UuanBnIiwgaGVpZ2h0ID0gMzAsIHdpZHRoID0gMTQpCmBgYAoKVGFrZSBkaXNzaW1pbGFyaXR5IHZhbHVlcyBmcm9tIHJhbmRvbSBub3JtYWwgZGlzdHJpYnV0aW9uIGZvciBlYWNoIHllYXIgZm9yIGVhY2ggcmVnaW9uLCBhbmQgdGhlbiBjYWxjdWxhdGUgc2xvcGUgKDEwMDAgdGltZXMpLiBEbyB0aGlzIGZvcjoKIC0gRmlzaGluZyBhbmQgdGVtcGVyYXR1cmUgdmFyeSBpbnRlcmFubnVhbGx5IHdpdGhpbiBzdXJ2ZXlzCiAtIFRlbXBlcmF0dXJlIGlzIGhlbGQgY29uc3RhbnQgKGFzIG1lYW4gb3ZlciB0aW1lIHNlcmllcyBmb3IgYSBzdXJ2ZXkpLCBidXQgZmlzaGluZyB2YXJpZXMgKGFsbG93cyB1cyB0byBsb29rIGF0IHJlbGF0aXZlIHZhcmlhbmNlIGV4cGxhaW5lZCkKIC0gRmlzaGluZyBpcyBoZWxkIGNvbnN0YW50IChhcyBtZWFuIG92ZXIgdGltZSBzZXJpZXMgZm9yIGEgc3VydmV5KSwgYnV0IHRlbXBlcmF0dXJlIHZhcmllcyAoYWxsb3dzIHVzIHRvIGxvb2sgYXQgcmVsYXRpdmUgdmFyaWFuY2UgZXhwbGFpbmVkKQogLSBCb3RoIGZpc2hpbmcgYW5kIHRlbXBlcmF0dXJlIGhlbGQgY29uc3RhbnQgKGFsbG93cyB1cyB0byBzZWUgcm9sZSBvZiBvdGhlciBjb21wb25lbnRzIG9mIHRoZSBtb2RlbCkKIApgYGB7cn0KIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMKI2Z1bGwgcHJlZGljdGlvbnMKIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMKI3RhYmxlIHdpdGggcHJlZGljdGVkIGRpc3NpbWlsYXJpdHkgdmFsdWVzIGFuZCBzdGFuZGFyZCBlcnJvciBvZiBhbGwgcHJlZGljdGVkIGRpc3NpbWlsYXJpdHkgdmFsdWVzIChieSB5ZWFyKQp0YWJsZSA8LSBkaXNzaW1pbGFyaXR5X2NvdmFyaWF0ZXNfZHJlZGdlLmR0X3ByZWRpY3Rpb25zWywuKHN1cnZleV91bml0LCBwcmVkX2Rpc3NpbSwgcHJlZF9zZSwgeWVhcildCiMwKSBtYWtlIGRhdGF0YWJsZSB0byBwb3B1bGF0ZQogIHByZWRpY3RlZF9kaXNzaW1fdHJlbmRzX3Jub3JtcnVucyA8LSBkYXRhLnRhYmxlKCkKIzEpIE5FVyBQUkVESUNURUQgVkFMVUVTIEZST00gRElTVFJJQlVUSU9OCmZvciAoaSBpbiAxOjEwMDApewogIHRhYmxlWyxybm9ybV9wcmVkIDo9IHJub3JtKDEsIG1lYW4gPSBwcmVkX2Rpc3NpbSwgc2QgPSBwcmVkX3NlKSwuKHllYXIsIHN1cnZleV91bml0KV0KIzIpIENBTENVTEFURSBMSU5FQVIgTU9ERUwgVE8gRVhUUkFDVCBTVVJWRVkgU1BFQ0lGSUMgVFJFTkQgVkFMVUVTCiAgamFjY2FyZF90b3RhbF9wcmVkaWN0ZWRfbG1fc2luZ2xlcnVuIDwtIGxtKHJub3JtX3ByZWQgfiB5ZWFyKnN1cnZleV91bml0LGRhdGEgPSB0YWJsZSkKCiAgbW9kZWxfY29lZnNfcmVkdWNlZF9wcmVkaWN0aW9uc19zaW5nbGVydW4gPC0gZGF0YS50YWJsZShzdW1tYXJ5KGphY2NhcmRfdG90YWxfcHJlZGljdGVkX2xtX3NpbmdsZXJ1bikkY29lZmZpY2llbnRzKQogIG1vZGVsX2NvZWZzX3JlZHVjZWRfcHJlZGljdGlvbnNfc2luZ2xlcnVuWyx2YXIgOj0gcm93bmFtZXMoc3VtbWFyeShqYWNjYXJkX3RvdGFsX3ByZWRpY3RlZF9sbV9zaW5nbGVydW4pJGNvZWZmaWNpZW50cyldCiAgCiAgI2xpbWl0IHRvIGludGVyYWN0aW9ucyBvbmx5IChjaGVjayB0aGlzIGlmIHRoZXJlIGFyZSBhbnkgbW9kZWwgY2hhbmdlcyEpIHJvdyAyIGFuZCByb3dzIDM0OjY0CiAgbW9kZWxfY29lZnNfcmVkdWNlZF9wcmVkaWN0aW9uc19zaW5nbGVydW4gPC0gbW9kZWxfY29lZnNfcmVkdWNlZF9wcmVkaWN0aW9uc19zaW5nbGVydW5bYygyLDM0OjY0KSxdCiAgCiAgI2FkanVzdCBzdXJ2ZXkgdW5pdCBuYW1lIGJ5IGRlbGV0aW5nIGJlZ2lubmluZyBvZiBzdHJpbmcKICBtb2RlbF9jb2Vmc19yZWR1Y2VkX3ByZWRpY3Rpb25zX3NpbmdsZXJ1blssc3VydmV5X3VuaXQgOj0gc3Vic3RyKHZhciwgMTcsIHN0cl9sZW5ndGgodmFyKSldW3ZhciA9PSAieWVhciIsc3VydmV5X3VuaXQgOj0gIkFJIl0KICAKICAjY2FsY3VsYXRlIGludGVyYWN0aW9uIGNvZWZmaWNpZW50cwogIEFJX2VzdGltYXRlIDwtIG1vZGVsX2NvZWZzX3JlZHVjZWRfcHJlZGljdGlvbnNfc2luZ2xlcnVuWzEsRXN0aW1hdGVdCiAgbW9kZWxfY29lZnNfcmVkdWNlZF9wcmVkaWN0aW9uc19zaW5nbGVydW5bMSxzdXJ2ZXlfdW5pdF9jb2VmZmljaWVudCA6PSBBSV9lc3RpbWF0ZV0KICBtb2RlbF9jb2Vmc19yZWR1Y2VkX3ByZWRpY3Rpb25zX3NpbmdsZXJ1blsyOjMyLHN1cnZleV91bml0X2NvZWZmaWNpZW50IDo9IChBSV9lc3RpbWF0ZSArIEVzdGltYXRlKV0KICAKICBwcmVkaWN0ZWRfZGlzc2ltX3RyZW5kc19ybm9ybXJ1bnMgPC0gcmJpbmQocHJlZGljdGVkX2Rpc3NpbV90cmVuZHNfcm5vcm1ydW5zLCBtb2RlbF9jb2Vmc19yZWR1Y2VkX3ByZWRpY3Rpb25zX3NpbmdsZXJ1blssLihzdXJ2ZXlfdW5pdCwgc3VydmV5X3VuaXRfY29lZmZpY2llbnQpXSkKICAKICBwcmludChpKQp9CiAgCiNyZWR1Y2UgdG8gbWVhbiBhbmQgc3RhbmRhcmQgZGV2aWF0aW9uCnByZWRpY3RlZF9kaXNzaW1fdHJlbmRzX3Jub3JtcnVuc1ssbWVhbl9kaXNzaW1fY29lZjo9IG1lYW4oc3VydmV5X3VuaXRfY29lZmZpY2llbnQpLHN1cnZleV91bml0XVssc2RfZGlzc2ltIDo9IHNkKHN1cnZleV91bml0X2NvZWZmaWNpZW50KSwuKHN1cnZleV91bml0KV0KCnByZWRpY3RlZF9kaXNzaW1fdHJlbmRzX3Jub3JtcnVucy5zdW1tYXJ5IDwtIHVuaXF1ZShwcmVkaWN0ZWRfZGlzc2ltX3RyZW5kc19ybm9ybXJ1bnNbLC4oc3VydmV5X3VuaXQsIG1lYW5fZGlzc2ltX2NvZWYsIHNkX2Rpc3NpbSldKQoKcHJlZGljdGVkX2Rpc3NpbV90cmVuZHNfcm5vcm1ydW5zLnN1bW1hcnlbLHByZWRfdHlwZSA6PSAiZnVsbCJdCgojIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIwojcHJlZGljdGlvbnMgd2l0aCB0ZW1wIGhlbGQgY29uc3RhbnQgYW5kIGZpc2hpbmcgc3RpbGwgdmFyeWluZyBmcm9tIHllYXIgdG8geWVhcgojIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIwojdGFibGUgd2l0aCBwcmVkaWN0ZWQgZGlzc2ltaWxhcml0eSB2YWx1ZXMgYW5kIHN0YW5kYXJkIGVycm9yIG9mIGFsbCBwcmVkaWN0ZWQgZGlzc2ltaWxhcml0eSB2YWx1ZXMgKGJ5IHllYXIpCnRhYmxlX2NvbnN0YW50dGVtcCA8LSBkaXNzaW1pbGFyaXR5X2NvdmFyaWF0ZXNfZHJlZGdlLmR0X3ByZWRpY3Rpb25zX2NvbnNpc3RlbnR0ZW1waW5yZWdbLC4oc3VydmV5X3VuaXQsIHByZWRfZGlzc2ltLCBwcmVkX3NlLCB5ZWFyKV0KIzApIG1ha2UgZGF0YXRhYmxlIHRvIHBvcHVsYXRlCiAgcHJlZGljdGVkX2Rpc3NpbV90cmVuZHNfcm5vcm1ydW5zX2NvbnN0YW50dGVtcCA8LSBkYXRhLnRhYmxlKCkKIzEpIE5FVyBQUkVESUNURUQgVkFMVUVTIEZST00gRElTVFJJQlVUSU9OCmZvciAoaSBpbiAxOjEwMDApewogIHRhYmxlX2NvbnN0YW50dGVtcFsscm5vcm1fcHJlZCA6PSBybm9ybSgxLCBtZWFuID0gcHJlZF9kaXNzaW0sIHNkID0gcHJlZF9zZSksLih5ZWFyLCBzdXJ2ZXlfdW5pdCldCiMyKSBDQUxDVUxBVEUgTElORUFSIE1PREVMIEZPUiBTTE9QRSBWQUxVRVMKICBqYWNjYXJkX3RvdGFsX3ByZWRpY3RlZF9sbV9zaW5nbGVydW5fY29uc3RhbnR0ZW1wIDwtIGxtKHJub3JtX3ByZWQgfiB5ZWFyKnN1cnZleV91bml0LGRhdGEgPSB0YWJsZV9jb25zdGFudHRlbXApCgogIG1vZGVsX2NvZWZzX3JlZHVjZWRfcHJlZGljdGlvbnNfc2luZ2xlcnVuX2NvbnN0YW50dGVtcCA8LSBkYXRhLnRhYmxlKHN1bW1hcnkoamFjY2FyZF90b3RhbF9wcmVkaWN0ZWRfbG1fc2luZ2xlcnVuX2NvbnN0YW50dGVtcCkkY29lZmZpY2llbnRzKQogIG1vZGVsX2NvZWZzX3JlZHVjZWRfcHJlZGljdGlvbnNfc2luZ2xlcnVuX2NvbnN0YW50dGVtcFssdmFyIDo9IHJvd25hbWVzKHN1bW1hcnkoamFjY2FyZF90b3RhbF9wcmVkaWN0ZWRfbG1fc2luZ2xlcnVuX2NvbnN0YW50dGVtcCkkY29lZmZpY2llbnRzKV0KICAKICAjbGltaXQgdG8gaW50ZXJhY3Rpb25zIG9ubHkgKGNoZWNrIHRoaXMgaWYgdGhlcmUgYXJlIGFueSBtb2RlbCBjaGFuZ2VzISkgcm93IDIgYW5kIHJvd3MgMzQ6NjQKICBtb2RlbF9jb2Vmc19yZWR1Y2VkX3ByZWRpY3Rpb25zX3NpbmdsZXJ1bl9jb25zdGFudHRlbXAgPC0gbW9kZWxfY29lZnNfcmVkdWNlZF9wcmVkaWN0aW9uc19zaW5nbGVydW5fY29uc3RhbnR0ZW1wW2MoMiwzNDo2NCksXQogIAogICNhZGp1c3Qgc3VydmV5IHVuaXQgbmFtZSBieSBkZWxldGluZyBiZWdpbm5pbmcgb2Ygc3RyaW5nCiAgbW9kZWxfY29lZnNfcmVkdWNlZF9wcmVkaWN0aW9uc19zaW5nbGVydW5fY29uc3RhbnR0ZW1wWyxzdXJ2ZXlfdW5pdCA6PSBzdWJzdHIodmFyLCAxNywgc3RyX2xlbmd0aCh2YXIpKV1bdmFyID09ICJ5ZWFyIixzdXJ2ZXlfdW5pdCA6PSAiQUkiXQogIAogICNjYWxjdWxhdGUgaW50ZXJhY3Rpb24gY29lZmZpY2llbnRzCiAgQUlfZXN0aW1hdGUgPC0gbW9kZWxfY29lZnNfcmVkdWNlZF9wcmVkaWN0aW9uc19zaW5nbGVydW5fY29uc3RhbnR0ZW1wWzEsRXN0aW1hdGVdCiAgbW9kZWxfY29lZnNfcmVkdWNlZF9wcmVkaWN0aW9uc19zaW5nbGVydW5fY29uc3RhbnR0ZW1wWzEsc3VydmV5X3VuaXRfY29lZmZpY2llbnQgOj0gQUlfZXN0aW1hdGVdCiAgbW9kZWxfY29lZnNfcmVkdWNlZF9wcmVkaWN0aW9uc19zaW5nbGVydW5fY29uc3RhbnR0ZW1wWzI6MzIsc3VydmV5X3VuaXRfY29lZmZpY2llbnQgOj0gKEFJX2VzdGltYXRlICsgRXN0aW1hdGUpXQogIAogIHByZWRpY3RlZF9kaXNzaW1fdHJlbmRzX3Jub3JtcnVuc19jb25zdGFudHRlbXAgPC0gcmJpbmQocHJlZGljdGVkX2Rpc3NpbV90cmVuZHNfcm5vcm1ydW5zX2NvbnN0YW50dGVtcCwgbW9kZWxfY29lZnNfcmVkdWNlZF9wcmVkaWN0aW9uc19zaW5nbGVydW5fY29uc3RhbnR0ZW1wWywuKHN1cnZleV91bml0LCBzdXJ2ZXlfdW5pdF9jb2VmZmljaWVudCldKQogIAogIHByaW50KGkpCn0KICAKI3JlZHVjZSB0byBtZWFuIGFuZCBzdGFuZGFyZCBkZXZpYXRpb24KcHJlZGljdGVkX2Rpc3NpbV90cmVuZHNfcm5vcm1ydW5zX2NvbnN0YW50dGVtcFssbWVhbl9kaXNzaW1fY29lZjo9IG1lYW4oc3VydmV5X3VuaXRfY29lZmZpY2llbnQpLHN1cnZleV91bml0XVssc2RfZGlzc2ltIDo9IHNkKHN1cnZleV91bml0X2NvZWZmaWNpZW50KSwuKHN1cnZleV91bml0KV0KCnByZWRpY3RlZF9kaXNzaW1fdHJlbmRzX3Jub3JtcnVuc2NvbnN0YW50X3RlbXAuc3VtbWFyeSA8LSB1bmlxdWUocHJlZGljdGVkX2Rpc3NpbV90cmVuZHNfcm5vcm1ydW5zX2NvbnN0YW50dGVtcFssLihzdXJ2ZXlfdW5pdCwgbWVhbl9kaXNzaW1fY29lZiwgc2RfZGlzc2ltKV0pCgpwcmVkaWN0ZWRfZGlzc2ltX3RyZW5kc19ybm9ybXJ1bnNjb25zdGFudF90ZW1wLnN1bW1hcnlbLHByZWRfdHlwZSA6PSAidGVtcF9jb25zdGFudCJdCgpwcmVkaWN0ZWRfZGlzc2ltX3RyZW5kc19ybm9ybXJ1bnMuc3VtbWFyeSA8LSByYmluZChwcmVkaWN0ZWRfZGlzc2ltX3RyZW5kc19ybm9ybXJ1bnMuc3VtbWFyeSwgcHJlZGljdGVkX2Rpc3NpbV90cmVuZHNfcm5vcm1ydW5zY29uc3RhbnRfdGVtcC5zdW1tYXJ5KQoKIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMKI3ByZWRpY3Rpb25zIHdpdGggZmlzaGluZyBoZWxkIGNvbnN0YW50IChhbmQgdGVtcGVyYXR1cmUgdmFyeWluZykKIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMKI3RhYmxlIHdpdGggcHJlZGljdGVkIGRpc3NpbWlsYXJpdHkgdmFsdWVzIGFuZCBzdGFuZGFyZCBlcnJvciBvZiBhbGwgcHJlZGljdGVkIGRpc3NpbWlsYXJpdHkgdmFsdWVzIChieSB5ZWFyKQp0YWJsZV9jb25zdGFudGZpc2hpbmcgPC0gZGlzc2ltaWxhcml0eV9jb3ZhcmlhdGVzX2RyZWRnZS5kdF9wcmVkaWN0aW9uc19jb25zaXN0ZW50ZmlzaGluZ2lucmVnWywuKHN1cnZleV91bml0LCBwcmVkX2Rpc3NpbSwgcHJlZF9zZSwgeWVhcildCiMwKSBtYWtlIGRhdGF0YWJsZSB0byBwb3B1bGF0ZQogIHByZWRpY3RlZF9kaXNzaW1fdHJlbmRzX3Jub3JtcnVuc19jb25zdGFudGZpc2hpbmcgPC0gZGF0YS50YWJsZSgpCiMxKSBORVcgUFJFRElDVEVEIFZBTFVFUyBGUk9NIERJU1RSSUJVVElPTgpmb3IgKGkgaW4gMToxMDAwKXsKICB0YWJsZV9jb25zdGFudGZpc2hpbmdbLHJub3JtX3ByZWQgOj0gcm5vcm0oMSwgbWVhbiA9IHByZWRfZGlzc2ltLCBzZCA9IHByZWRfc2UpLC4oeWVhciwgc3VydmV5X3VuaXQpXQojMikgQ0FMQ1VMQVRFIExJTkVBUiBNT0RFTCBGT1IgU0xPUEUgVkFMVUVTCiAgamFjY2FyZF90b3RhbF9wcmVkaWN0ZWRfbG1fc2luZ2xlcnVuX2NvbnN0YW50ZmlzaGluZyA8LSBsbShybm9ybV9wcmVkIH4geWVhcipzdXJ2ZXlfdW5pdCxkYXRhID0gdGFibGVfY29uc3RhbnRmaXNoaW5nKQoKICBtb2RlbF9jb2Vmc19yZWR1Y2VkX3ByZWRpY3Rpb25zX3NpbmdsZXJ1bl9jb25zdGFudGZpc2hpbmcgPC0gZGF0YS50YWJsZShzdW1tYXJ5KGphY2NhcmRfdG90YWxfcHJlZGljdGVkX2xtX3NpbmdsZXJ1bl9jb25zdGFudGZpc2hpbmcpJGNvZWZmaWNpZW50cykKICBtb2RlbF9jb2Vmc19yZWR1Y2VkX3ByZWRpY3Rpb25zX3NpbmdsZXJ1bl9jb25zdGFudGZpc2hpbmdbLHZhciA6PSByb3duYW1lcyhzdW1tYXJ5KGphY2NhcmRfdG90YWxfcHJlZGljdGVkX2xtX3NpbmdsZXJ1bl9jb25zdGFudGZpc2hpbmcpJGNvZWZmaWNpZW50cyldCiAgCiAgI2xpbWl0IHRvIGludGVyYWN0aW9ucyBvbmx5IChjaGVjayB0aGlzIGlmIHRoZXJlIGFyZSBhbnkgbW9kZWwgY2hhbmdlcyEpIHJvdyAyIGFuZCByb3dzIDM0OjY0CiAgbW9kZWxfY29lZnNfcmVkdWNlZF9wcmVkaWN0aW9uc19zaW5nbGVydW5fY29uc3RhbnRmaXNoaW5nIDwtIG1vZGVsX2NvZWZzX3JlZHVjZWRfcHJlZGljdGlvbnNfc2luZ2xlcnVuX2NvbnN0YW50ZmlzaGluZ1tjKDIsMzQ6NjQpLF0KICAKICAjYWRqdXN0IHN1cnZleSB1bml0IG5hbWUgYnkgZGVsZXRpbmcgYmVnaW5uaW5nIG9mIHN0cmluZwogIG1vZGVsX2NvZWZzX3JlZHVjZWRfcHJlZGljdGlvbnNfc2luZ2xlcnVuX2NvbnN0YW50ZmlzaGluZ1ssc3VydmV5X3VuaXQgOj0gc3Vic3RyKHZhciwgMTcsIHN0cl9sZW5ndGgodmFyKSldW3ZhciA9PSAieWVhciIsc3VydmV5X3VuaXQgOj0gIkFJIl0KICAKICAjY2FsY3VsYXRlIGludGVyYWN0aW9uIGNvZWZmaWNpZW50cwogIEFJX2VzdGltYXRlIDwtIG1vZGVsX2NvZWZzX3JlZHVjZWRfcHJlZGljdGlvbnNfc2luZ2xlcnVuX2NvbnN0YW50ZmlzaGluZ1sxLEVzdGltYXRlXQogIG1vZGVsX2NvZWZzX3JlZHVjZWRfcHJlZGljdGlvbnNfc2luZ2xlcnVuX2NvbnN0YW50ZmlzaGluZ1sxLHN1cnZleV91bml0X2NvZWZmaWNpZW50IDo9IEFJX2VzdGltYXRlXQogIG1vZGVsX2NvZWZzX3JlZHVjZWRfcHJlZGljdGlvbnNfc2luZ2xlcnVuX2NvbnN0YW50ZmlzaGluZ1syOjMyLHN1cnZleV91bml0X2NvZWZmaWNpZW50IDo9IChBSV9lc3RpbWF0ZSArIEVzdGltYXRlKV0KICAKICBwcmVkaWN0ZWRfZGlzc2ltX3RyZW5kc19ybm9ybXJ1bnNfY29uc3RhbnRmaXNoaW5nIDwtIHJiaW5kKHByZWRpY3RlZF9kaXNzaW1fdHJlbmRzX3Jub3JtcnVuc19jb25zdGFudGZpc2hpbmcsIG1vZGVsX2NvZWZzX3JlZHVjZWRfcHJlZGljdGlvbnNfc2luZ2xlcnVuX2NvbnN0YW50ZmlzaGluZ1ssLihzdXJ2ZXlfdW5pdCwgc3VydmV5X3VuaXRfY29lZmZpY2llbnQpXSkKICAKICBwcmludChpKQp9CiAgCiNyZWR1Y2UgdG8gbWVhbiBhbmQgc3RhbmRhcmQgZGV2aWF0aW9uCnByZWRpY3RlZF9kaXNzaW1fdHJlbmRzX3Jub3JtcnVuc19jb25zdGFudGZpc2hpbmdbLG1lYW5fZGlzc2ltX2NvZWY6PSBtZWFuKHN1cnZleV91bml0X2NvZWZmaWNpZW50KSxzdXJ2ZXlfdW5pdF1bLHNkX2Rpc3NpbSA6PSBzZChzdXJ2ZXlfdW5pdF9jb2VmZmljaWVudCksLihzdXJ2ZXlfdW5pdCldCgpwcmVkaWN0ZWRfZGlzc2ltX3RyZW5kc19ybm9ybXJ1bnNjb25zdGFudF9maXNoaW5nLnN1bW1hcnkgPC0gdW5pcXVlKHByZWRpY3RlZF9kaXNzaW1fdHJlbmRzX3Jub3JtcnVuc19jb25zdGFudGZpc2hpbmdbLC4oc3VydmV5X3VuaXQsIG1lYW5fZGlzc2ltX2NvZWYsIHNkX2Rpc3NpbSldKQoKcHJlZGljdGVkX2Rpc3NpbV90cmVuZHNfcm5vcm1ydW5zY29uc3RhbnRfZmlzaGluZy5zdW1tYXJ5WyxwcmVkX3R5cGUgOj0gImZpc2hpbmdfY29uc3RhbnQiXQoKcHJlZGljdGVkX2Rpc3NpbV90cmVuZHNfcm5vcm1ydW5zLnN1bW1hcnkgPC0gcmJpbmQocHJlZGljdGVkX2Rpc3NpbV90cmVuZHNfcm5vcm1ydW5zLnN1bW1hcnksIHByZWRpY3RlZF9kaXNzaW1fdHJlbmRzX3Jub3JtcnVuc2NvbnN0YW50X2Zpc2hpbmcuc3VtbWFyeSkKCgojIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIwojcHJlZGljdGlvbnMgd2l0aCBib3RoIGZpc2hpbmcgYW5kIHRlbXBlcmF0dXJlIGhlbGQgY29uc3RhbnQgKHZhcmlhYmlsaXR5IGdvZXMgdG8gb3RoZXIgZmFjdG9ycyB3ZSBkb24ndCBhY2NvdW50IGZvcikKIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMKI3RhYmxlIHdpdGggcHJlZGljdGVkIGRpc3NpbWlsYXJpdHkgdmFsdWVzIGFuZCBzdGFuZGFyZCBlcnJvciBvZiBhbGwgcHJlZGljdGVkIGRpc3NpbWlsYXJpdHkgdmFsdWVzIChieSB5ZWFyKQp0YWJsZV9jb25zdGFudHRlbXBmaXNoaW5nIDwtIGRpc3NpbWlsYXJpdHlfY292YXJpYXRlc19kcmVkZ2UuZHRfcHJlZGljdGlvbnNfY29uc2lzdGVudHRlbXBmaXNoaW5naW5yZWdbLC4oc3VydmV5X3VuaXQsIHByZWRfZGlzc2ltLCBwcmVkX3NlLCB5ZWFyKV0KIzApIG1ha2UgZGF0YXRhYmxlIHRvIHBvcHVsYXRlCiAgcHJlZGljdGVkX2Rpc3NpbV90cmVuZHNfcm5vcm1ydW5zX2NvbnN0YW50dGVtcGZpc2hpbmcgPC0gZGF0YS50YWJsZSgpCiMxKSBORVcgUFJFRElDVEVEIFZBTFVFUyBGUk9NIERJU1RSSUJVVElPTgpmb3IgKGkgaW4gMToxMDAwKXsKICB0YWJsZV9jb25zdGFudHRlbXBmaXNoaW5nWyxybm9ybV9wcmVkIDo9IHJub3JtKDEsIG1lYW4gPSBwcmVkX2Rpc3NpbSwgc2QgPSBwcmVkX3NlKSwuKHllYXIsIHN1cnZleV91bml0KV0KIzIpIENBTENVTEFURSBMSU5FQVIgTU9ERUwgRk9SIFNMT1BFIFZBTFVFUwogIGphY2NhcmRfdG90YWxfcHJlZGljdGVkX2xtX3NpbmdsZXJ1bl9jb25zdGFudHRlbXBmaXNoaW5nIDwtIGxtKHJub3JtX3ByZWQgfiB5ZWFyKnN1cnZleV91bml0LGRhdGEgPSB0YWJsZV9jb25zdGFudHRlbXBmaXNoaW5nKQoKICBtb2RlbF9jb2Vmc19yZWR1Y2VkX3ByZWRpY3Rpb25zX3NpbmdsZXJ1bl9jb25zdGFudHRlbXBmaXNoaW5nIDwtIGRhdGEudGFibGUoc3VtbWFyeShqYWNjYXJkX3RvdGFsX3ByZWRpY3RlZF9sbV9zaW5nbGVydW5fY29uc3RhbnR0ZW1wZmlzaGluZykkY29lZmZpY2llbnRzKQogIG1vZGVsX2NvZWZzX3JlZHVjZWRfcHJlZGljdGlvbnNfc2luZ2xlcnVuX2NvbnN0YW50dGVtcGZpc2hpbmdbLHZhciA6PSByb3duYW1lcyhzdW1tYXJ5KGphY2NhcmRfdG90YWxfcHJlZGljdGVkX2xtX3NpbmdsZXJ1bl9jb25zdGFudHRlbXBmaXNoaW5nKSRjb2VmZmljaWVudHMpXQogIAogICNsaW1pdCB0byBpbnRlcmFjdGlvbnMgb25seSAoY2hlY2sgdGhpcyBpZiB0aGVyZSBhcmUgYW55IG1vZGVsIGNoYW5nZXMhKSByb3cgMiBhbmQgcm93cyAzNDo2NAogIG1vZGVsX2NvZWZzX3JlZHVjZWRfcHJlZGljdGlvbnNfc2luZ2xlcnVuX2NvbnN0YW50dGVtcGZpc2hpbmcgPC0gbW9kZWxfY29lZnNfcmVkdWNlZF9wcmVkaWN0aW9uc19zaW5nbGVydW5fY29uc3RhbnR0ZW1wZmlzaGluZ1tjKDIsMzQ6NjQpLF0KICAKICAjYWRqdXN0IHN1cnZleSB1bml0IG5hbWUgYnkgZGVsZXRpbmcgYmVnaW5uaW5nIG9mIHN0cmluZwogIG1vZGVsX2NvZWZzX3JlZHVjZWRfcHJlZGljdGlvbnNfc2luZ2xlcnVuX2NvbnN0YW50dGVtcGZpc2hpbmdbLHN1cnZleV91bml0IDo9IHN1YnN0cih2YXIsIDE3LCBzdHJfbGVuZ3RoKHZhcikpXVt2YXIgPT0gInllYXIiLHN1cnZleV91bml0IDo9ICJBSSJdCiAgCiAgI2NhbGN1bGF0ZSBpbnRlcmFjdGlvbiBjb2VmZmljaWVudHMKICBBSV9lc3RpbWF0ZSA8LSBtb2RlbF9jb2Vmc19yZWR1Y2VkX3ByZWRpY3Rpb25zX3NpbmdsZXJ1bl9jb25zdGFudHRlbXBmaXNoaW5nWzEsRXN0aW1hdGVdCiAgbW9kZWxfY29lZnNfcmVkdWNlZF9wcmVkaWN0aW9uc19zaW5nbGVydW5fY29uc3RhbnR0ZW1wZmlzaGluZ1sxLHN1cnZleV91bml0X2NvZWZmaWNpZW50IDo9IEFJX2VzdGltYXRlXQogIG1vZGVsX2NvZWZzX3JlZHVjZWRfcHJlZGljdGlvbnNfc2luZ2xlcnVuX2NvbnN0YW50dGVtcGZpc2hpbmdbMjozMixzdXJ2ZXlfdW5pdF9jb2VmZmljaWVudCA6PSAoQUlfZXN0aW1hdGUgKyBFc3RpbWF0ZSldCiAgCiAgcHJlZGljdGVkX2Rpc3NpbV90cmVuZHNfcm5vcm1ydW5zX2NvbnN0YW50dGVtcGZpc2hpbmcgPC0gcmJpbmQocHJlZGljdGVkX2Rpc3NpbV90cmVuZHNfcm5vcm1ydW5zX2NvbnN0YW50dGVtcGZpc2hpbmcsIG1vZGVsX2NvZWZzX3JlZHVjZWRfcHJlZGljdGlvbnNfc2luZ2xlcnVuX2NvbnN0YW50dGVtcGZpc2hpbmdbLC4oc3VydmV5X3VuaXQsIHN1cnZleV91bml0X2NvZWZmaWNpZW50KV0pCiAgCiAgcHJpbnQoaSkKfQogIAojcmVkdWNlIHRvIG1lYW4gYW5kIHN0YW5kYXJkIGRldmlhdGlvbgpwcmVkaWN0ZWRfZGlzc2ltX3RyZW5kc19ybm9ybXJ1bnNfY29uc3RhbnR0ZW1wZmlzaGluZ1ssbWVhbl9kaXNzaW1fY29lZjo9IG1lYW4oc3VydmV5X3VuaXRfY29lZmZpY2llbnQpLHN1cnZleV91bml0XVssc2RfZGlzc2ltIDo9IHNkKHN1cnZleV91bml0X2NvZWZmaWNpZW50KSwuKHN1cnZleV91bml0KV0KCnByZWRpY3RlZF9kaXNzaW1fdHJlbmRzX3Jub3JtcnVuc2NvbnN0YW50X3RlbXBmaXNoaW5nLnN1bW1hcnkgPC0gdW5pcXVlKHByZWRpY3RlZF9kaXNzaW1fdHJlbmRzX3Jub3JtcnVuc19jb25zdGFudHRlbXBmaXNoaW5nWywuKHN1cnZleV91bml0LCBtZWFuX2Rpc3NpbV9jb2VmLCBzZF9kaXNzaW0pXSkKCnByZWRpY3RlZF9kaXNzaW1fdHJlbmRzX3Jub3JtcnVuc2NvbnN0YW50X3RlbXBmaXNoaW5nLnN1bW1hcnlbLHByZWRfdHlwZSA6PSAiZmlzaGluZ19hbmRfdGVtcF9jb25zdGFudCJdCgpwcmVkaWN0ZWRfZGlzc2ltX3RyZW5kc19ybm9ybXJ1bnMuc3VtbWFyeSA8LSByYmluZChwcmVkaWN0ZWRfZGlzc2ltX3RyZW5kc19ybm9ybXJ1bnMuc3VtbWFyeSwgcHJlZGljdGVkX2Rpc3NpbV90cmVuZHNfcm5vcm1ydW5zY29uc3RhbnRfdGVtcGZpc2hpbmcuc3VtbWFyeSkKYGBgCgpQbG90dGluZyBvYnNlcnZlZCB2cyBwcmVkaWN0ZWQKYGBge3J9CgpqYWNjYXJkX2Zpc2hpbmdfdGVtcF9tb2RlbF9vYnNlcnZlZF9wcmVkaWN0ZWRfZHQgPC0gamFjY2FyZF90b3RhbF9jb2Vmcy5yW3ByZWRpY3RlZF9kaXNzaW1fdHJlbmRzX3Jub3JtcnVucy5zdW1tYXJ5LCBvbiA9ICJzdXJ2ZXlfdW5pdCJdCgpqYWNjYXJkX2Zpc2hpbmdfdGVtcF9tb2RlbF9vYnNlcnZlZF9wcmVkaWN0ZWRfZHRbLHByZWRfbG93ZXIgOj0gbWVhbl9kaXNzaW1fY29lZi1zZF9kaXNzaW1dWyxwcmVkX3VwcGVyIDo9IG1lYW5fZGlzc2ltX2NvZWYrc2RfZGlzc2ltXQoKI0ZVTEwgTU9ERUwsIGJvdGggdGVtcGVyYXR1cmUgYW5kIGZpc2hpbmcgYXJlIGFsbG93ZWQgdG8gdmFyeQpqYWNjYXJkX2Zpc2hpbmdfdGVtcF9tb2RlbF9vYnNlcnZlZF9wcmVkaWN0ZWRfbG0gPC0gbG0oc3VydmV5X3VuaXRfY29lZmZpY2llbnQgfiBtZWFuX2Rpc3NpbV9jb2VmLCBkYXRhID0gamFjY2FyZF9maXNoaW5nX3RlbXBfbW9kZWxfb2JzZXJ2ZWRfcHJlZGljdGVkX2R0W3ByZWRfdHlwZSA9PSAiZnVsbCJdKQpzdW1tYXJ5KGphY2NhcmRfZmlzaGluZ190ZW1wX21vZGVsX29ic2VydmVkX3ByZWRpY3RlZF9sbSkgI1JeMiAwLjQyCgooamFjY2FyZF9maXNoaW5nX3RlbXBfbW9kZWxfb2JzZXJ2ZWRfcHJlZGljdGVkIDwtIGdncGxvdChqYWNjYXJkX2Zpc2hpbmdfdGVtcF9tb2RlbF9vYnNlcnZlZF9wcmVkaWN0ZWRfZHRbcHJlZF90eXBlID09ICJmdWxsIl0pICsKICBnZW9tX2Vycm9yYmFyKGFlcyh4ID0gbWVhbl9kaXNzaW1fY29lZiwgeW1pbiA9IGx3ciwgeW1heCA9IHVwciksIGNvbG9yID0gImxpZ2h0Z3JleSIsIGxpbmV3aWR0aCA9IDAuNCkgKwogIGdlb21fZXJyb3JiYXJoKGFlcyh5ID0gc3VydmV5X3VuaXRfY29lZmZpY2llbnQsIHhtaW4gPSBtZWFuX2Rpc3NpbV9jb2VmLXNkX2Rpc3NpbSwgeG1heCA9IG1lYW5fZGlzc2ltX2NvZWYrc2RfZGlzc2ltKSwgY29sb3IgPSAibGlnaHRncmV5IiwgbGluZXdpZHRoID0gMC40KSArCiAgZ2VvbV9wb2ludChhZXMoeSA9IHN1cnZleV91bml0X2NvZWZmaWNpZW50LCB4ID0gbWVhbl9kaXNzaW1fY29lZikpICsKICBnZW9tX3Ntb290aChhZXMoeSA9IHN1cnZleV91bml0X2NvZWZmaWNpZW50LCB4ID0gbWVhbl9kaXNzaW1fY29lZiksIGNvbG9yID0gImRhcmtncmV5IixsaW5ldHlwZSA9ICJkb3R0ZWQiLCBtZXRob2QgPSAibG0iKSArCiAgZ2VvbV9hYmxpbmUoYWVzKHNsb3BlID0gMSwgaW50ZXJjZXB0ID0gMCkpICsKICBsaW1zKHggPSBjKG1pbihqYWNjYXJkX2Zpc2hpbmdfdGVtcF9tb2RlbF9vYnNlcnZlZF9wcmVkaWN0ZWRfZHQkcHJlZF9sb3dlciksbWF4KGphY2NhcmRfZmlzaGluZ190ZW1wX21vZGVsX29ic2VydmVkX3ByZWRpY3RlZF9kdCRwcmVkX3VwcGVyKSkpICsKICBsYWJzKHkgPSAiT2JzZXJ2ZWQgzrItZGl2ZXJzaXR5IHRyZW5kIix4ID0gIlByZWRpY3RlZCDOsi1kaXZlcnNpdHkgdHJlbmRcbiIpICsKICB0aGVtZV9jbGFzc2ljKCkKKQoKI2Zpc2hpbmcgY29uc3RhbnQgKGZpc2hpbmcgY29uc3RhbnQ7IHRlbXBlcmF0dXJlIHZhcmllcyBvbmx5KQpqYWNjYXJkX2Zpc2hpbmdfY29uc3RhbnRfbW9kZWxfb2JzZXJ2ZWRfcHJlZGljdGVkX2xtIDwtIGxtKHN1cnZleV91bml0X2NvZWZmaWNpZW50IH4gbWVhbl9kaXNzaW1fY29lZiwgZGF0YSA9IGphY2NhcmRfZmlzaGluZ190ZW1wX21vZGVsX29ic2VydmVkX3ByZWRpY3RlZF9kdFtwcmVkX3R5cGUgPT0gImZpc2hpbmdfY29uc3RhbnQiXSkKc3VtbWFyeShqYWNjYXJkX2Zpc2hpbmdfY29uc3RhbnRfbW9kZWxfb2JzZXJ2ZWRfcHJlZGljdGVkX2xtKSAKI1RlbXBlcmF0dXJlIGFzIGEgcHJlZGljdG9yLCBub3QgZmlzaGluZyA9IFJeMiA9IDAuMjggKGRyb3AgaW4gMTIlIG9mIHZhcmlhbmNlIGV4cGxhaW5lZCB3aGVuIHlvdSBsb3NlIGZpc2hpbmcgYXMgcHJlZGljdG9yKQoKKGphY2NhcmRfZmlzaGluZ19jb25zdGFudF9tb2RlbF9vYnNlcnZlZF9wcmVkaWN0ZWQgPC0gZ2dwbG90KGphY2NhcmRfZmlzaGluZ190ZW1wX21vZGVsX29ic2VydmVkX3ByZWRpY3RlZF9kdFtwcmVkX3R5cGUgPT0gImZpc2hpbmdfY29uc3RhbnQiXSkgKwpnZW9tX2Vycm9yYmFyKGFlcyh4ID0gbWVhbl9kaXNzaW1fY29lZiwgeW1pbiA9IGx3ciwgeW1heCA9IHVwciksIGNvbG9yID0gImxpZ2h0Z3JleSIsIGxpbmV3aWR0aCA9IDAuNCkgKwogIGdlb21fZXJyb3JiYXJoKGFlcyh5ID0gc3VydmV5X3VuaXRfY29lZmZpY2llbnQsIHhtaW4gPSBtZWFuX2Rpc3NpbV9jb2VmLXNkX2Rpc3NpbSwgeG1heCA9IG1lYW5fZGlzc2ltX2NvZWYrc2RfZGlzc2ltKSwgY29sb3IgPSAibGlnaHRncmV5IiwgbGluZXdpZHRoID0gMC40KSArCiAgZ2VvbV9wb2ludChhZXMoeSA9IHN1cnZleV91bml0X2NvZWZmaWNpZW50LCB4ID0gbWVhbl9kaXNzaW1fY29lZikpICsKICAgIGdlb21fc21vb3RoKGFlcyh5ID0gc3VydmV5X3VuaXRfY29lZmZpY2llbnQsIHggPSBtZWFuX2Rpc3NpbV9jb2VmKSwgY29sb3IgPSAiZGFya2dyZXkiLGxpbmV0eXBlID0gImRvdHRlZCIsIG1ldGhvZCA9ICJsbSIpICsKICBnZW9tX2FibGluZShhZXMoc2xvcGUgPSAxLCBpbnRlcmNlcHQgPSAwKSkgKwogICAgICBsaW1zKHggPSBjKG1pbihqYWNjYXJkX2Zpc2hpbmdfdGVtcF9tb2RlbF9vYnNlcnZlZF9wcmVkaWN0ZWRfZHQkcHJlZF9sb3dlciksbWF4KGphY2NhcmRfZmlzaGluZ190ZW1wX21vZGVsX29ic2VydmVkX3ByZWRpY3RlZF9kdCRwcmVkX3VwcGVyKSkpICsKICBsYWJzKHkgPSAiT2JzZXJ2ZWQgzrItZGl2ZXJzaXR5IHRyZW5kIix4ID0gIlByZWRpY3RlZCDOsi1kaXZlcnNpdHkgdHJlbmRcbih0ZW1wZXJhdHVyZSB2YXJpZXMgZmlzaGluZyBjb25zdGFudCkiKSArCiAgdGhlbWVfY2xhc3NpYygpCikKCiN0ZW1wIGNvbnN0YW50IChmaXNoaW5nIG9ubHk7IHRlbXBlcmF0dXJlIGNvbnN0YW50KQpqYWNjYXJkX3RlbXBlcmF0dXJlX2NvbnN0YW50X21vZGVsX29ic2VydmVkX3ByZWRpY3RlZF9sbSA8LSBsbShzdXJ2ZXlfdW5pdF9jb2VmZmljaWVudCB+IG1lYW5fZGlzc2ltX2NvZWYsIGRhdGEgPSBqYWNjYXJkX2Zpc2hpbmdfdGVtcF9tb2RlbF9vYnNlcnZlZF9wcmVkaWN0ZWRfZHRbcHJlZF90eXBlID09ICJ0ZW1wX2NvbnN0YW50Il0pCnN1bW1hcnkoamFjY2FyZF90ZW1wZXJhdHVyZV9jb25zdGFudF9tb2RlbF9vYnNlcnZlZF9wcmVkaWN0ZWRfbG0pICMwLjE4IERyb3AgaW4gMjIlIG9mIHZhcmlhbmNlIGV4cGxhaW5lZCB3aGVuIHlvdSBsb3NlIHRlbXBlcmF0dXJlIGFzIGEgcHJlZGljdG9yCgooamFjY2FyZF90ZW1wZXJhdHVyZV9jb25zdGFudF9tb2RlbF9vYnNlcnZlZF9wcmVkaWN0ZWQgPC0gZ2dwbG90KGphY2NhcmRfZmlzaGluZ190ZW1wX21vZGVsX29ic2VydmVkX3ByZWRpY3RlZF9kdFtwcmVkX3R5cGUgPT0gInRlbXBfY29uc3RhbnQiXSkgKwogIGdlb21fZXJyb3JiYXIoYWVzKHggPSBtZWFuX2Rpc3NpbV9jb2VmLCB5bWluID0gbHdyLCB5bWF4ID0gdXByKSwgY29sb3IgPSAibGlnaHRncmV5IiwgbGluZXdpZHRoID0gMC40KSArCiAgZ2VvbV9lcnJvcmJhcmgoYWVzKHkgPSBzdXJ2ZXlfdW5pdF9jb2VmZmljaWVudCwgeG1pbiA9IG1lYW5fZGlzc2ltX2NvZWYtc2RfZGlzc2ltLCB4bWF4ID0gbWVhbl9kaXNzaW1fY29lZitzZF9kaXNzaW0pLCBjb2xvciA9ICJsaWdodGdyZXkiLCBsaW5ld2lkdGggPSAwLjQpICsKICBnZW9tX3BvaW50KGFlcyh5ID0gc3VydmV5X3VuaXRfY29lZmZpY2llbnQsIHggPSBtZWFuX2Rpc3NpbV9jb2VmKSkgKwogICAgZ2VvbV9zbW9vdGgoYWVzKHkgPSBzdXJ2ZXlfdW5pdF9jb2VmZmljaWVudCwgeCA9IG1lYW5fZGlzc2ltX2NvZWYpLCBjb2xvciA9ICJkYXJrZ3JleSIsbGluZXR5cGUgPSAiZG90dGVkIiwgbWV0aG9kID0gImxtIikgKwogIGdlb21fYWJsaW5lKGFlcyhzbG9wZSA9IDEsIGludGVyY2VwdCA9IDApKSArCiAgICAgIGxpbXMoeCA9IGMobWluKGphY2NhcmRfZmlzaGluZ190ZW1wX21vZGVsX29ic2VydmVkX3ByZWRpY3RlZF9kdCRwcmVkX2xvd2VyKSxtYXgoamFjY2FyZF9maXNoaW5nX3RlbXBfbW9kZWxfb2JzZXJ2ZWRfcHJlZGljdGVkX2R0JHByZWRfdXBwZXIpKSkgKwogIGxhYnMoeSA9ICJPYnNlcnZlZCDOsi1kaXZlcnNpdHkgdHJlbmQiLHggPSAiUHJlZGljdGVkIM6yLWRpdmVyc2l0eSB0cmVuZFxuKGZpc2hpbmcgdmFyaWVzIHRlbXBlcmF0dXJlIGNvbnN0YW50KSIpICsKICB0aGVtZV9jbGFzc2ljKCkKKQoKI2JvdGggdGVtcGVyYXR1cmUgYW5kIGZpc2ggaGVsZCBjb25zdGFudApqYWNjYXJkX2Zpc2hpbmdfdGVtcF9tb2RlbF9vYnNlcnZlZF9wcmVkaWN0ZWRfdGVtcGZpc2hjb25zdGFudGluc3VydmV5X2xtIDwtIGxtKHN1cnZleV91bml0X2NvZWZmaWNpZW50IH4gbWVhbl9kaXNzaW1fY29lZiwgZGF0YSA9IGphY2NhcmRfZmlzaGluZ190ZW1wX21vZGVsX29ic2VydmVkX3ByZWRpY3RlZF9kdFtwcmVkX3R5cGUgPT0gImZpc2hpbmdfYW5kX3RlbXBfY29uc3RhbnQiXSkKc3VtbWFyeShqYWNjYXJkX2Zpc2hpbmdfdGVtcF9tb2RlbF9vYnNlcnZlZF9wcmVkaWN0ZWRfdGVtcGZpc2hjb25zdGFudGluc3VydmV5X2xtKSAjJTExIAoKKGphY2NhcmRfZmlzaGluZ190ZW1wX21vZGVsX29ic2VydmVkX3ByZWRpY3RlZF90ZW1wZmlzaGNvbnN0YW50aW5zdXJ2ZXkgPC0gZ2dwbG90KGphY2NhcmRfZmlzaGluZ190ZW1wX21vZGVsX29ic2VydmVkX3ByZWRpY3RlZF9kdFtwcmVkX3R5cGUgPT0gImZpc2hpbmdfYW5kX3RlbXBfY29uc3RhbnQiXSkgKwpnZW9tX2Vycm9yYmFyKGFlcyh4ID0gbWVhbl9kaXNzaW1fY29lZiwgeW1pbiA9IGx3ciwgeW1heCA9IHVwciksIGNvbG9yID0gImxpZ2h0Z3JleSIsIGxpbmV3aWR0aCA9IDAuNCkgKwogIGdlb21fZXJyb3JiYXJoKGFlcyh5ID0gc3VydmV5X3VuaXRfY29lZmZpY2llbnQsIHhtaW4gPSBtZWFuX2Rpc3NpbV9jb2VmLXNkX2Rpc3NpbSwgeG1heCA9IG1lYW5fZGlzc2ltX2NvZWYrc2RfZGlzc2ltKSwgY29sb3IgPSAibGlnaHRncmV5IiwgbGluZXdpZHRoID0gMC40KSArCiAgZ2VvbV9wb2ludChhZXMoeSA9IHN1cnZleV91bml0X2NvZWZmaWNpZW50LCB4ID0gbWVhbl9kaXNzaW1fY29lZikpICsKICAgIGdlb21fc21vb3RoKGFlcyh5ID0gc3VydmV5X3VuaXRfY29lZmZpY2llbnQsIHggPSBtZWFuX2Rpc3NpbV9jb2VmKSwgY29sb3IgPSAiZGFya2dyZXkiLGxpbmV0eXBlID0gImRvdHRlZCIsIG1ldGhvZCA9ICJsbSIpKwogIGdlb21fYWJsaW5lKGFlcyhzbG9wZSA9IDEsIGludGVyY2VwdCA9IDApKSArCiAgICAgIGxpbXMoeCA9IGMobWluKGphY2NhcmRfZmlzaGluZ190ZW1wX21vZGVsX29ic2VydmVkX3ByZWRpY3RlZF9kdCRwcmVkX2xvd2VyKSxtYXgoamFjY2FyZF9maXNoaW5nX3RlbXBfbW9kZWxfb2JzZXJ2ZWRfcHJlZGljdGVkX2R0JHByZWRfdXBwZXIpKSkgKwogIGxhYnMoeSA9ICJPYnNlcnZlZCDOsi1kaXZlcnNpdHkgdHJlbmQiLHggPSAiUHJlZGljdGVkIM6yLWRpdmVyc2l0eSB0cmVuZFxuKGZpc2hpbmcgYW5kIHRlbXBlcmF0dXJlIGNvbnN0YW50KSIpICsKICB0aGVtZV9jbGFzc2ljKCkKKQoKCiNtZXJnZQpqYWNjYXJkX2Zpc2hpbmdfc2J0X21vZGVsX29ic2VydmVkX3ByZWRpY3RlZF9tZXJnZSA8LSBwbG90X2dyaWQoamFjY2FyZF9maXNoaW5nX3RlbXBfbW9kZWxfb2JzZXJ2ZWRfcHJlZGljdGVkICsgdGhlbWUocGxvdC5tYXJnaW4gPSB1bml0KGMoMC4xLDAuMywwLjEsMC4xKSwiY20iKSksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGphY2NhcmRfZmlzaGluZ19jb25zdGFudF9tb2RlbF9vYnNlcnZlZF9wcmVkaWN0ZWQgKyB0aGVtZShwbG90Lm1hcmdpbiA9IHVuaXQoYygwLjEsMC4zLDAuMSwwLjEpLCJjbSIpKSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgamFjY2FyZF90ZW1wZXJhdHVyZV9jb25zdGFudF9tb2RlbF9vYnNlcnZlZF9wcmVkaWN0ZWQgKyB0aGVtZShwbG90Lm1hcmdpbiA9IHVuaXQoYygwLjEsMC4zLDAuMSwwLjEpLCJjbSIpKSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgamFjY2FyZF9maXNoaW5nX3RlbXBfbW9kZWxfb2JzZXJ2ZWRfcHJlZGljdGVkX3RlbXBmaXNoY29uc3RhbnRpbnN1cnZleSArIHRoZW1lKHBsb3QubWFyZ2luID0gdW5pdChjKDAuMSwwLjMsMC4xLDAuMSksImNtIikpLCBuY29sID0gMiwgbGFiZWxzID0gYygiYS4iLCJiLiIsImMuIiwiZC4iKSkKCmdnc2F2ZShqYWNjYXJkX2Zpc2hpbmdfc2J0X21vZGVsX29ic2VydmVkX3ByZWRpY3RlZF9tZXJnZSwgcGF0aCA9IGhlcmU6OmhlcmUoImZpZ3VyZXMiKSxmaWxlbmFtZSA9ICJqYWNjYXJkX2Zpc2hpbmdfc2J0X21vZGVsX29ic2VydmVkX3ByZWRpY3RlZF9tZXJnZS5qcGciLCBoZWlnaHQgPTYsIHdpZHRoID0gOCkKCgpgYGAKCkxldCdzIHZpc3VhbGl6ZSBtb2RlbCBjb2VmZmljaWVudHMgd2l0aCB0ZW1wZXJhdHVyZSBhbmQgZmlzaGluZyAoc2ltaWxhciB0byBmaWd1cmUgMikKbW9kZWxfYXZnX3ZhbHVlcwpgYGB7cn0KbW9kZWxfYXZnX3ZhbHVlcwoKaW50ZXJhY3Rpb25fYXZnX21vZGVsX2NvZWYgPC0gbW9kZWxfYXZnX3ZhbHVlc1tjKDUsMzc6OTkpLC4oY29lZl9uYW1lLCBjb2VmLCBzZSldCgojaW5zZXJ0IEFJCmludGVyYWN0aW9uX2F2Z19tb2RlbF9jb2VmWzE6MixzdXJ2ZXlfdW5pdCA6PSAiQUkiXVsxOjIsY29lZl90cnVlIDo9IGNvZWZdWzE6MixwcmVkaWN0b3IgOj0gYygiUmVsYXRpdmUgZmlzaGluZyBjYXRjaCIsIk1pbmltdW0gdGVtcGVyYXR1cmUiKV0KCiNPdGhlciBzdW1tZWRfdG9ubmVzX3NjYWxlZF9ieXJlZwppbnRlcmFjdGlvbl9hdmdfbW9kZWxfY29lZlszOjMzLHN1cnZleV91bml0IDo9IHN1YnN0cihjb2VmX25hbWUsIDM5LCBzdHJfbGVuZ3RoKGNvZWZfbmFtZSkpXVszOjMzLGNvZWZfdHJ1ZSA6PSBpbnRlcmFjdGlvbl9hdmdfbW9kZWxfY29lZlsxLGNvZWZfdHJ1ZV0rY29lZl1bMzozMyxwcmVkaWN0b3IgOj0gIlJlbGF0aXZlIGZpc2hpbmcgY2F0Y2giXQoKI090aGVyIHllYXJseV9taW5fYnlwb2ludF9hdmcuc2NhbGVkYWNyb3NzYWxsCmludGVyYWN0aW9uX2F2Z19tb2RlbF9jb2VmWzM0OjY0LHN1cnZleV91bml0IDo9IHN1YnN0cihjb2VmX25hbWUsIHN0cl9sZW5ndGgoInN1cnZleV91bml0IikrMSwgc3RyX2xlbmd0aChjb2VmX25hbWUpLXN0cl9sZW5ndGgoInllYXJseV9taW5fYnlwb2ludF9hdmcuc2NhbGVkYWNyb3NzYWxsIiktMSldWzM0OjY0LGNvZWZfdHJ1ZSA6PSBpbnRlcmFjdGlvbl9hdmdfbW9kZWxfY29lZlsyLGNvZWZfdHJ1ZV0rY29lZl1bMzQ6NjQscHJlZGljdG9yIDo9ICJNaW5pbXVtIHRlbXBlcmF0dXJlIl0KCiNyZW9yZGVyIHRlbXBlcmF0dXJlIGFuZCBmaXNoaW5nCmludGVyYWN0aW9uX2F2Z19tb2RlbF9jb2VmWyxwcmVkaWN0b3IgOj0gZmFjdG9yKHByZWRpY3RvciwgbGV2ZWxzID0gYygiTWluaW11bSB0ZW1wZXJhdHVyZSIsIlJlbGF0aXZlIGZpc2hpbmcgY2F0Y2giKSldCgojbGluayBmb3IgZnVsbCBzdXJ2ZXkgbmFtZQppbnRlcmFjdGlvbl9hdmdfbW9kZWxfY29lZiA8LSBjb2xvcl9saW5rW2ludGVyYWN0aW9uX2F2Z19tb2RlbF9jb2VmLCBvbiA9ICJzdXJ2ZXlfdW5pdCJdCgojcmVvcmRlciBieSBzdXJ2ZXlfdW5pdAppbnRlcmFjdGlvbl9hdmdfbW9kZWxfY29lZlssU3VydmV5X05hbWVfU2Vhc29uIDo9IHJlb3JkZXIoU3VydmV5X05hbWVfU2Vhc29uLCBzdXJ2ZXlfdW5pdCwgZGVjcmVhc2luZyA9IFRSVUUpXQoKI21hcmsgc2lnbmlmaWNhbmNlCmludGVyYWN0aW9uX2F2Z19tb2RlbF9jb2VmWyxTaWduaWZpY2FudCA6PSBpZmVsc2UoKGNvZWZfdHJ1ZS1zZSA+IDAgJiBjb2VmX3RydWUrc2UgPiAwKSB8IChjb2VmX3RydWUtc2UgPCAwICYgY29lZl90cnVlK3NlIDwgMCksVCxGKV0KCgojUGxvdCBib3RoCnNidF9maXNoaW5nX2F2Z19tb2RlbF9jb2VmIDwtIGdncGxvdCgpICsKICBnZW9tX2hsaW5lKHlpbnRlcmNlcHQgPSAwLCBsaW5ldHlwZSA9ICJkb3R0ZWQiKSArCmdlb21fcG9pbnQoZGF0YSA9IGludGVyYWN0aW9uX2F2Z19tb2RlbF9jb2VmLCBhZXMoeCA9IFN1cnZleV9OYW1lX1NlYXNvbiwgeSA9IGNvZWZfdHJ1ZSwgY29sb3IgPSBTaWduaWZpY2FudCkpICsgIApnZW9tX2Vycm9yYmFyKGRhdGEgPSBpbnRlcmFjdGlvbl9hdmdfbW9kZWxfY29lZiwgYWVzKHggPSBTdXJ2ZXlfTmFtZV9TZWFzb24sIHltaW4gPSBjb2VmX3RydWUtc2UsIHltYXggPSBjb2VmX3RydWUrc2UsIGNvbG9yID0gU2lnbmlmaWNhbnQpLCB3aWR0aCA9IDApICsKICBzY2FsZV9jb2xvcl9tYW51YWwodmFsdWVzID0gYygiZGFya2dyZXkiLCJibGFjayIpKSArCmZhY2V0X3dyYXAofnByZWRpY3Rvciwgc2NhbGVzID0gImZyZWVfeCIpICsKc2NhbGVfeF9kaXNjcmV0ZShsaW1pdHMgPSByZXYpICsKICBsYWJzKHkgPSAiQ29lZmZpY2llbnQiLCB4ID0gIiIpICsKY29vcmRfZmxpcCgpICsKdGhlbWVfY2xhc3NpYygpCiAgCgoKYGBgClBsb3QgYWxsIG90aGVyIGNvZWZmaWNpZW50cyBpbiBhdmVyYWdlZCBtb2RlbApgYGB7cn0KbW9kZWxfYXZnX3ZhbHVlcy5ub25maXNob3J0ZW1wIDwtIG1vZGVsX2F2Z192YWx1ZXNbYygyLDMsNCwxMDA6MTA0KSxdCgojbWFyayBzaWduaWZpY2FuY2UKbW9kZWxfYXZnX3ZhbHVlcy5ub25maXNob3J0ZW1wWyxTaWduaWZpY2FudCA6PSBpZmVsc2UoKGNvZWYtc2UgPiAwICYgY29lZitzZSA+IDApIHwgKGNvZWYtc2UgPCAwICYgY29lZitzZSA8IDApLFQsRildCgojbW9yZSBoZWxwZnVsIG5hbWVzIGZvciB2YXJpYWJsZXMKbW9kZWxfYXZnX3ZhbHVlcy5ub25maXNob3J0ZW1wWyxWYXJpYWJsZSA6PSBjKCJBcmVhIiwiSnVsaWFuIGRheSIsIlNwZWNpZXMgY291bnQiLCJOdW1iZXIgb2YgdG93cyIsIkxhdGl0dWRlIHJhbmdlIiwiRGVwdGgiLCJMYXRpdHVkZSIsIkRlcHRoIHJhbmdlIildCgojbWFrZSBmYWN0b3Igd2l0aCBvcmRlcgptb2RlbF9hdmdfdmFsdWVzLm5vbmZpc2hvcnRlbXBbLFZhcmlhYmxlIDo9IGZhY3RvcihWYXJpYWJsZSwgbGV2ZWxzID0gYygiQXJlYSIsIkp1bGlhbiBkYXkiLCJTcGVjaWVzIGNvdW50IiwiTnVtYmVyIG9mIHRvd3MiLCJEZXB0aCIsIkRlcHRoIHJhbmdlIiwiTGF0aXR1ZGUiLCJMYXRpdHVkZSByYW5nZSIpKV0KCgojcGxvdAphbGxfYXZnX21vZGVsX2NvZWYgPC0gZ2dwbG90KCkgKyAKZ2VvbV9wb2ludChkYXRhID0gbW9kZWxfYXZnX3ZhbHVlcy5ub25maXNob3J0ZW1wLCBhZXMoeCA9IFZhcmlhYmxlLCB5ID0gY29lZiwgY29sb3IgPSBTaWduaWZpY2FudCkpICsgIApnZW9tX2Vycm9yYmFyKGRhdGEgPSBtb2RlbF9hdmdfdmFsdWVzLm5vbmZpc2hvcnRlbXAsIGFlcyh4ID0gVmFyaWFibGUsIHltaW4gPSBjb2VmLXNlLCB5bWF4ID0gY29lZitzZSwgY29sb3IgPSBTaWduaWZpY2FudCksIHdpZHRoID0gMCkgKwogIHNjYWxlX2NvbG9yX21hbnVhbCh2YWx1ZXMgPSBjKCJkYXJrZ3JleSIsImJsYWNrIikpICsKZ2VvbV9obGluZSh5aW50ZXJjZXB0ID0gMCkgKwpzY2FsZV94X2Rpc2NyZXRlKGxpbWl0cyA9IHJldikgKwogIGxhYnMoeSA9ICJDb2VmZmljaWVudCIsIHggPSAiXG5cblxuIikgKwpjb29yZF9mbGlwKCkgKwp0aGVtZV9jbGFzc2ljKCkKCiNwbG90CmFsbF9idXRfbGF0X2F2Z19tb2RlbF9jb2VmIDwtIGdncGxvdCgpICsgCmdlb21fcG9pbnQoZGF0YSA9IG1vZGVsX2F2Z192YWx1ZXMubm9uZmlzaG9ydGVtcFtWYXJpYWJsZSA9PSAiTGF0aXR1ZGUiXSwgYWVzKHggPSBWYXJpYWJsZSwgeSA9IGNvZWYsIGNvbG9yID0gU2lnbmlmaWNhbnQpKSArICAKZ2VvbV9lcnJvcmJhcihkYXRhID0gbW9kZWxfYXZnX3ZhbHVlcy5ub25maXNob3J0ZW1wW1ZhcmlhYmxlID09ICJMYXRpdHVkZSJdLCBhZXMoeCA9IFZhcmlhYmxlLCB5bWluID0gY29lZi1zZSwgeW1heCA9IGNvZWYrc2UsIGNvbG9yID0gU2lnbmlmaWNhbnQpLCB3aWR0aCA9IDApICsKICBzY2FsZV9jb2xvcl9tYW51YWwodmFsdWVzID0gYygiZGFya2dyZXkiLCJibGFjayIpKSArCmdlb21faGxpbmUoeWludGVyY2VwdCA9IDApICsKc2NhbGVfeF9kaXNjcmV0ZShsaW1pdHMgPSByZXYpICsKICBsYWJzKHkgPSAiQ29lZmZpY2llbnQiLCB4ID0gIk1vZGVsIHZhcmlhYmxlIikgKwpjb29yZF9mbGlwKCkgKwp0aGVtZV9jbGFzc2ljKCkKCiNwbG90CmxhdF9hdmdfbW9kZWxfY29lZiA8LSBnZ3Bsb3QoKSArIApnZW9tX3BvaW50KGRhdGEgPSBtb2RlbF9hdmdfdmFsdWVzLm5vbmZpc2hvcnRlbXBbVmFyaWFibGUgIT0gIkxhdGl0dWRlIl0sIGFlcyh4ID0gVmFyaWFibGUsIHkgPSBjb2VmLCBjb2xvciA9IFNpZ25pZmljYW50KSkgKyAgCmdlb21fZXJyb3JiYXIoZGF0YSA9IG1vZGVsX2F2Z192YWx1ZXMubm9uZmlzaG9ydGVtcFtWYXJpYWJsZSAhPSAiTGF0aXR1ZGUiXSwgYWVzKHggPSBWYXJpYWJsZSwgeW1pbiA9IGNvZWYtc2UsIHltYXggPSBjb2VmK3NlLCBjb2xvciA9IFNpZ25pZmljYW50KSwgd2lkdGggPSAwKSArCiAgc2NhbGVfY29sb3JfbWFudWFsKHZhbHVlcyA9IGMoImRhcmtncmV5IiwiYmxhY2siKSkgKwpnZW9tX2hsaW5lKHlpbnRlcmNlcHQgPSAwKSArCnNjYWxlX3hfZGlzY3JldGUobGltaXRzID0gcmV2KSArCiAgbGFicyh5ID0gIkNvZWZmaWNpZW50IiwgeCA9ICJNb2RlbCB2YXJpYWJsZSIpICsKY29vcmRfZmxpcCgpICsKdGhlbWVfY2xhc3NpYygpCgojbWVyZ2UgaW50byBzaW5nbGUgcGxvdAoKbW9kZWxfY29lZl9zdW1tYXJ5X3NidF9qYWNjYXJkIDwtIGNvd3Bsb3Q6OnBsb3RfZ3JpZChzYnRfZmlzaGluZ19hdmdfbW9kZWxfY29lZit0aGVtZShsZWdlbmQucG9zaXRpb24gPSAibnVsbCIsIGF4aXMudGl0bGUueCA9IGVsZW1lbnRfYmxhbmsoKSksYWxsX2F2Z19tb2RlbF9jb2VmK3RoZW1lKGxlZ2VuZC5wb3NpdGlvbiA9ICJudWxsIiksIG5jb2wgPSAxLCBsYWJlbHMgPSBjKCIgIGEuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYi4iLCIgICAgICAgIGMuIiksIGxhYmVsX3kgPSAwLjk5LCByZWxfaGVpZ2h0cyA9IGMoMywxKSkKCmdnc2F2ZShtb2RlbF9jb2VmX3N1bW1hcnlfc2J0X2phY2NhcmQsIHBhdGggPSBoZXJlOjpoZXJlKCJmaWd1cmVzIiksZmlsZW5hbWUgPSAibW9kZWxfY29lZl9zdW1tYXJ5X3NidF9qYWNjYXJkLmpwZyIsIGhlaWdodCA9IDYuNSwgd2lkdGggPSA4LCB1bml0ID0gImluIikKCgpgYGAKCg==